Packages
library(tidyverse)
library(ggrepel)
library(extraDistr) # install.packages("extraDistr")
library(HDInterval) # install.packages("HDAPerval")
library(tidybayes) # install.packages("tidybayes")
library(bayesplot) # install.packages("bayesplot")
library(modelr)
library(broom.mixed) # install.packages("broom.mixed")
library(brms) # install.packages("brms")
library(ggthemes)
library(patchwork)
library(ggokabeito) # install.packages("ggokabeito")
theme_set(theme_minimal())
# Creating a theme function used for visualizations
theme_clean <- function() {
theme_minimal(base_family = "Arial") +
theme(panel.grid.minor = element_blank(),
plot.title = element_text(face = "bold"),
axis.title = element_text(face = "bold"),
strip.text = element_text(face = "bold", size = rel(1), hjust = 0),
strip.background = element_rect(fill = "grey80", color = NA),
legend.title = element_text(face = "bold"))
}
Loading the models
model_Int <- base::readRDS(file = "Models/brms_Int.rds")
model_Nat <- base::readRDS(file = "Models/brms_Nat.rds")
model_articRate <- base::readRDS(file = "Models/brms_articRate.rds")
model_AAVS <- base::readRDS(file = "Models/brms_AAVS.rds")
model_M1s <- base::readRDS(file = "Models/brms_M1s.rds")
model_M1sh <- base::readRDS(file = "Models/brms_M1sh.rds")
model_M2s <- base::readRDS(file = "Models/brms_M2s.rds")
model_M2sh <- base::readRDS(file = "Models/brms_M2sh.rds")
01. Reliability
workingData_Int <- base::readRDS(file = "workingData/data_Int.RDS")
workingData_Nat <- base::readRDS(file = "workingData/data_Nat.RDS")
interRel_plotData <- rbind(
workingData_Int$data %>%
dplyr::select(c(
gorilla_id,
speaker_id,
`Time Point` = time_point,
Group = group,
Sex = sex,
age,
rating
)
) %>%
dplyr::mutate(
Measure = "Intelligibility"
),
workingData_Nat$data %>%
dplyr::select(c(
gorilla_id,
speaker_id,
`Time Point` = time_point,
Group = group,
Sex = sex,
age,
rating
)
) %>%
dplyr::mutate(
Measure = "Naturalness"
)
) %>%
dplyr::filter(gorilla_id != "10237851") %>%
dplyr::group_by(speaker_id, `Time Point`, Group, Sex, age, Measure) %>%
dplyr::summarise(M = mean(rating),
sd = sd(rating)) %>%
dplyr::ungroup() %>%
dplyr::mutate(`Time Point` = factor(`Time Point`,
levels = c("before",
"sensors",
"after"),
labels = c("Before Sensors",
"With Sensors",
"After Sensors")),
Measure = factor(Measure,
levels = c("Intelligibility",
"Naturalness"),
labels = c("Intelligibility Ratings",
"Naturalness Ratings")),
Group = factor(Group,
levels = c("Control",
"PD"),
labels = c("Control",
"PwPD")))
`summarise()` has grouped output by 'speaker_id', 'Time Point', 'Group', 'Sex', 'age'. You can override using the `.groups` argument.
interRel_plot <- interRel_plotData %>%
ggplot() +
aes(
x = M,
y = sd,
color = Group,
shape = `Time Point`
) +
geom_point() +
facet_wrap(~Measure) +
labs(x = "Average Rating (Mean)",
y = "Rating Variability (sd)",
title = "Inter-listener Reliability",
#subtitle = "The mean and standard deviation of ratings across speakers and time points."
) +
ggokabeito::scale_color_okabe_ito(order = c(2,
#5,
#4,
1)) +
ggthemes::theme_clean() &
theme(
strip.text.x = element_text(hjust = 0, size = 12),
strip.text.y = element_text(angle = 0),
plot.background = element_blank(),
#panel.margin=unit(.05, "lines"),
panel.border = element_rect(color = "black", fill = NA, size = 1),
strip.background = element_rect(color = "black", size = 1),
#panel.border = element_rect(color = "black", fill = NA, size = 1),
legend.position = "bottom",
legend.box="vertical",
legend.background = element_rect(color = NA),
aspect.ratio = 1)
Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
Please use the `linewidth` argument instead.
interRel_plot
ggsave(plot = interRel_plot,
file = "Figures/Fig_Inter-Listener Reliability.png",
height = 5,
width = 6.5,
units = "in",
scale = 1,
bg = "white")

02. Artic Rate
Expected Posteriors
# Generate expected predictions from the posterior
data_posterior_articRate <- model_articRate %>%
tidybayes::epred_draws(
newdata = tidyr::expand_grid(
group = c("Control", "PD"),
time_point = c("before", "sensors", "after"),
sex = c("Male", "Female"),
age = 66.88,
),
re_formula = NA
) %>%
group_by(.draw, group, time_point) %>%
summarize(.epred = mean(.epred), .groups = "drop") %>%
dplyr::mutate(
group = factor(
group,
levels = c("Control", "PD"),
labels = c("Control", "PwPD")
),
#grouping = paste(sex, group, sep = " - "),
#grouping = factor(grouping,
# levels = c("Male - Control",
# "Male - PwPD",
# "Female - Control",
# "Female - PwPD")),
time_point = factor(
time_point,
levels = c("before", "sensors", "after"),
labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
)
)
plot_grandMean_articRate <- ggplot(data_posterior_articRate,
aes(x = .epred, y = time_point, fill = group)) +
stat_halfeye(alpha = .9) +
ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
labs(x = "Predicted articulation rate (syl/s)", y = NULL,
fill = "Group",
title = "(a) Posterior Predictions",
subtitle = "Predicted articulation rate after\ncontrolling for speaker age and sex.") +
scale_y_discrete(limits = rev) +
theme_clean() +
#facet_grid(sex~.) +
theme(legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle),
#panel.border = element_rect(color = "grey", fill = NA)
) +
guides(fill = guide_legend(nrow = 1))
ME: Timepoint x Group
robust_articRate <- rio::import("workingData/data_articRate.RDS")$pairwise %>%
dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_articRate <- model_articRate %>%
emmeans::emmeans( ~ time_point | group, epred = TRUE, re_formula = NA, ) %>%
emmeans::contrast(method = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::filter(contrast != "after - sensors")
# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_articRate %>%
emmeans::emmeans( ~ time_point * group, epred = TRUE, re_formula = NA) %>%
emmeans::contrast(interaction = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::rename(contrast = time_point_revpairwise, group = group_revpairwise) %>%
dplyr::filter(contrast != "after - sensors")
data_meContrasts_articRate <- base::rbind(data_meContrasts_articRate, interaction_contrast) %>%
dplyr::mutate(group = case_when(
group == "PD" ~ "PwPD",
group == "Control" ~ "Control",
group == "PD - Control" ~ "PwPD -\nControl"
)) %>%
base::merge(., robust_articRate)
plot_RQ1_articRate <- ggplot(
data_meContrasts_articRate %>%
dplyr::filter(contrast == "sensors - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of sensors effects (syl/s)",
y = NULL,
title = "(b) Research Question 1",
subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ1_articRate

plot_RQ2_articRate <- ggplot(
data_meContrasts_articRate %>%
dplyr::filter(contrast == "after - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of after-sensor\neffects (syl/s)",
y = NULL,
title = "(c) Research Question 2",
subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ2_articRate

# Combined plot
plot_articRate <- plot_grandMean_articRate + plot_RQ1_articRate + plot_RQ2_articRate +
patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect"
) +
plot_annotation(title = "Articulation Rate", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
theme = theme_clean()) &
theme(legend.position = "bottom")
plot_articRate
ggsave(
plot = plot_articRate,
filename = "Figures/Fig_articRate.png",
height = 6,
width = 10,
unit = "in",
scale = .9,
bg = "white"
)

03. AAVS
Expected Posteriors
# Generate expected predictions from the posterior
data_posterior_AAVS <- model_AAVS %>%
tidybayes::epred_draws(
newdata = tidyr::expand_grid(
group = c("Control", "PD"),
time_point = c("before", "sensors", "after"),
sex = c("Male", "Female"),
age = mean(model_AAVS$data$age),
artic_rate = mean(model_AAVS$data$artic_rate),
),
re_formula = NA
) %>%
group_by(.draw, group, time_point) %>%
summarize(.epred = mean(.epred), .groups = "drop") %>%
dplyr::mutate(
group = factor(
group,
levels = c("Control", "PD"),
labels = c("Control", "PwPD")
),
#grouping = paste(sex, group, sep = " - "),
#grouping = factor(grouping,
# levels = c("Male - Control",
# "Male - PwPD",
# "Female - Control",
# "Female - PwPD")),
time_point = factor(
time_point,
levels = c("before", "sensors", "after"),
labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
)
)
plot_grandMean_AAVS <- ggplot(data_posterior_AAVS, aes(x = .epred, y = time_point, fill = group)) +
stat_halfeye(alpha = .9) +
ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
labs(x = "Predicted AAVS (mel²)", y = NULL,
fill = "Group",
title = "(a) Posterior Predictions",
subtitle = "Predicted AAVS after controlling for\nspeaker age, sex, and articulation rate.") +
scale_y_discrete(limits = rev) +
#coord_cartesian(xlim = c(.65,1)) +
theme_clean() +
#facet_grid(sex~.) +
theme(legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle),
#panel.border = element_rect(color = "grey", fill = NA)
) +
guides(fill = guide_legend(nrow = 1))
plot_grandMean_AAVS

ME: Timepoint x Group
robust_AAVS <- rio::import("workingData/data_AAVS.RDS")$pairwise %>%
dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_AAVS <- model_AAVS %>%
emmeans::emmeans(~ time_point | group,
epred = TRUE,
re_formula = NA,) %>%
emmeans::contrast(method = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::filter(contrast != "after - sensors") %>%
dplyr::mutate(group = case_when(
group == "PD" ~ "PwPD",
group == "Control" ~ "Control"
))
# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_AAVS %>%
emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
emmeans::contrast(interaction = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::rename(contrast = time_point_revpairwise,
group = group_revpairwise) %>%
dplyr::filter(contrast != "after - sensors") %>%
dplyr::mutate(group = case_when(
group == "PD - Control" ~ "PwPD -\nControl"
))
data_meContrasts_AAVS <- base::rbind(data_meContrasts_AAVS, interaction_contrast) %>%
base::merge(., robust_AAVS) %>%
dplyr::mutate(
robust = factor(robust, levels = c("not robust", "robust")))
#bayestestR::p_direction(data_meContrasts_AAVS)
plot_RQ1_AAVS <- ggplot(
data_meContrasts_AAVS %>%
dplyr::filter(contrast == "sensors - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of sensors effects (mel²)",
y = NULL,
title = "(b) Research Question 1",
subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ1_AAVS

plot_RQ2_AAVS <- ggplot(
data_meContrasts_AAVS %>%
dplyr::filter(contrast == "after - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of after-sensor\neffects (mel²)",
y = NULL,
title = "(c) Research Question 2",
subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ2_AAVS

# Combined plot
plot_AAVS <- plot_grandMean_AAVS + plot_RQ1_AAVS + plot_RQ2_AAVS +
patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect") +
plot_annotation(title = "Articulatory Acoustic Vowel Space", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
theme = theme_clean()) &
theme(legend.position = "bottom")
plot_AAVS
ggsave(
plot = plot_AAVS,
filename = "Figures/Fig_AAVS.png",
height = 6,
width = 10,
unit = "in",
scale = .9,
bg = "white"
)

04. M1
/s/ - Expected Posteriors
# Generate expected predictions from the posterior
data_posterior_M1s <- model_M1s %>%
tidybayes::epred_draws(
newdata = tidyr::expand_grid(
group = c("Control", "PD"),
time_point = c("before", "sensors", "after"),
sex = c("Male", "Female"),
age = mean(model_M1s$data$age),
artic_rate = mean(model_M1s$data$artic_rate),
),
re_formula = NA
) %>%
group_by(.draw, group, time_point) %>%
summarize(.epred = mean(.epred), .groups = "drop") %>%
dplyr::mutate(
group = factor(
group,
levels = c("Control", "PD"),
labels = c("Control", "PwPD")
),
#grouping = paste(sex, group, sep = " - "),
#grouping = factor(grouping,
# levels = c("Male - Control",
# "Male - PwPD",
# "Female - Control",
# "Female - PwPD")),
time_point = factor(
time_point,
levels = c("before", "sensors", "after"),
labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
)
)
/s/ - ME: Timepoint x Group
robust_M1s <- rio::import("workingData/data_M1s.RDS")$pairwise %>%
dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_M1s <- model_M1s %>%
emmeans::emmeans(~ time_point | group,
epred = TRUE,
re_formula = NA,) %>%
emmeans::contrast(method = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::filter(contrast != "after - sensors")
# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_M1s %>%
emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
emmeans::contrast(interaction = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::rename(contrast = time_point_revpairwise,
group = group_revpairwise) %>%
dplyr::filter(contrast != "after - sensors")
data_meContrasts_M1s <- base::rbind(data_meContrasts_M1s, interaction_contrast) %>%
dplyr::mutate(group = case_when(
group == "PD" ~ "PwPD",
group == "Control" ~ "Control",
group == "PD - Control" ~ "PwPD -\nControl"
)) %>%
base::merge(., robust_M1s) %>%
dplyr::mutate(robust = factor(robust,
levels = c("not robust",
"robust")))
#bayestestR::p_direction(data_meContrasts_M1s)
/sh/ - Expected Posteriors
# Generate expected predictions from the posterior
data_posterior_M1sh <- model_M1sh %>%
tidybayes::epred_draws(
newdata = tidyr::expand_grid(
group = c("Control", "PD"),
time_point = c("before", "sensors", "after"),
sex = c("Male", "Female"),
age = mean(model_M1sh$data$age),
artic_rate = mean(model_M1sh$data$artic_rate),
),
re_formula = NA
) %>%
group_by(.draw, group, time_point) %>%
summarize(.epred = mean(.epred), .groups = "drop") %>%
dplyr::mutate(
group = factor(
group,
levels = c("Control", "PD"),
labels = c("Control", "PwPD")
),
#grouping = paste(sex, group, sep = " - "),
#grouping = factor(grouping,
# levels = c("Male - Control",
# "Male - PwPD",
# "Female - Control",
# "Female - PwPD")),
time_point = factor(
time_point,
levels = c("before", "sensors", "after"),
labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
)
)
/sh/ - ME: Timepoint x Group
robust_M1sh <- rio::import("workingData/data_M1sh.RDS")$pairwise %>%
dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_M1sh <- model_M1sh %>%
emmeans::emmeans(~ time_point | group,
epred = TRUE,
re_formula = NA,) %>%
emmeans::contrast(method = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::filter(contrast != "after - sensors")
# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_M1sh %>%
emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
emmeans::contrast(interaction = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::rename(contrast = time_point_revpairwise,
group = group_revpairwise) %>%
dplyr::filter(contrast != "after - sensors")
data_meContrasts_M1sh <- base::rbind(data_meContrasts_M1sh, interaction_contrast) %>%
dplyr::mutate(group = case_when(
group == "PD" ~ "PwPD",
group == "Control" ~ "Control",
group == "PD - Control" ~ "PwPD -\nControl"
)) %>%
base::merge(., robust_M1sh) %>%
dplyr::mutate(robust = factor(robust,
levels = c("not robust",
"robust")))
#bayestestR::p_direction(data_meContrasts_M1sh)
Combined
Expected Posteriors
# Generate expected predictions from the posterior
data_posterior_M1 <- rbind(data_posterior_M1s %>%
dplyr::mutate(sound = "/s/"),
data_posterior_M1sh %>%
dplyr::mutate(sound = "/ʃ/"))
plot_grandMean_M1 <- ggplot(data_posterior_M1,
aes(x = .epred, y = time_point,
fill = group)) +
stat_halfeye(alpha = .9) +
ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
labs(x = "Predicted M1 (kHz)", y = NULL,
fill = "Group",
title = "(a) Posterior Predictions",
subtitle = "Predicted M1 after controlling for\nspeaker age, sex, and articulation rate.") +
scale_y_discrete(limits = rev) +
theme_clean() +
facet_wrap(~sound, ncol = 1) +
theme(legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)) +
guides(fill = guide_legend(nrow = 1))
ME: Timepoint x Group
data_meContrasts_M1 <- rbind(data_meContrasts_M1s %>%
dplyr::mutate(sound = "/s/"),
data_meContrasts_M1sh %>%
dplyr::mutate(sound = "/ʃ/"))
#bayestestR::p_direction(data_meContrasts_M1)
plot_RQ1_M1 <- ggplot(
data_meContrasts_M1 %>%
dplyr::filter(contrast == "sensors - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of sensors effects (kHz)",
y = NULL,
title = "(b) Research Question 1",
subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
facet_wrap(~sound, ncol = 1) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ1_M1

plot_RQ2_M1 <- ggplot(
data_meContrasts_M1 %>%
dplyr::filter(contrast == "after - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of after-sensor\neffects (kHz)",
y = NULL,
title = "(c) Research Question 2",
subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
facet_wrap(~sound, ncol = 1) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ2_M1

# Combined plot
plot_M1 <- plot_grandMean_M1 + plot_RQ1_M1 + plot_RQ2_M1 +
patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect") +
plot_annotation(title = "Spectral Center of Gravity (M1)", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
theme = theme_clean()) &
theme(legend.position = "bottom")
plot_M1
ggsave(
plot = plot_M1,
filename = "Figures/Fig_M1.png",
height = 7,
width = 10,
unit = "in",
scale = .9,
bg = "white"
)

05. M2
/s/ - Expected Posteriors
# Generate expected predictions from the posterior
data_posterior_M2s <- model_M2s %>%
tidybayes::epred_draws(
newdata = tidyr::expand_grid(
group = c("Control", "PD"),
time_point = c("before", "sensors", "after"),
sex = c("Male", "Female"),
age = mean(model_M2s$data$age),
artic_rate = mean(model_M2s$data$artic_rate),
),
re_formula = NA
) %>%
group_by(.draw, group, time_point) %>%
summarize(.epred = mean(.epred), .groups = "drop") %>%
dplyr::mutate(
group = factor(
group,
levels = c("Control", "PD"),
labels = c("Control", "PwPD")
),
#grouping = paste(sex, group, sep = " - "),
#grouping = factor(grouping,
# levels = c("Male - Control",
# "Male - PwPD",
# "Female - Control",
# "Female - PwPD")),
time_point = factor(
time_point,
levels = c("before", "sensors", "after"),
labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
)
)
/s/ - ME: Timepoint x Group
robust_M2s <- rio::import("workingData/data_M2s.RDS")$pairwise %>%
dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_M2s <- model_M2s %>%
emmeans::emmeans(~ time_point | group,
epred = TRUE,
re_formula = NA,) %>%
emmeans::contrast(method = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::filter(contrast != "after - sensors")
# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_M2s %>%
emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
emmeans::contrast(interaction = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::rename(contrast = time_point_revpairwise,
group = group_revpairwise) %>%
dplyr::filter(contrast != "after - sensors")
data_meContrasts_M2s <- base::rbind(data_meContrasts_M2s, interaction_contrast) %>%
dplyr::mutate(group = case_when(
group == "PD" ~ "PwPD",
group == "Control" ~ "Control",
group == "PD - Control" ~ "PwPD -\nControl"
)) %>%
base::merge(., robust_M2s) %>%
dplyr::mutate(robust = factor(robust,
levels = c("not robust",
"robust")))
#bayestestR::p_direction(data_meContrasts_M2s)
/sh/ - Expected Posteriors
# Generate expected predictions from the posterior
data_posterior_M2sh <- model_M2sh %>%
tidybayes::epred_draws(
newdata = tidyr::expand_grid(
group = c("Control", "PD"),
time_point = c("before", "sensors", "after"),
sex = c("Male", "Female"),
age = mean(model_M2sh$data$age),
artic_rate = mean(model_M2sh$data$artic_rate),
),
re_formula = NA
) %>%
group_by(.draw, group, time_point) %>%
summarize(.epred = mean(.epred), .groups = "drop") %>%
dplyr::mutate(
group = factor(
group,
levels = c("Control", "PD"),
labels = c("Control", "PwPD")
),
#grouping = paste(sex, group, sep = " - "),
#grouping = factor(grouping,
# levels = c("Male - Control",
# "Male - PwPD",
# "Female - Control",
# "Female - PwPD")),
time_point = factor(
time_point,
levels = c("before", "sensors", "after"),
labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
)
)
/sh/ - ME: Timepoint x Group
robust_M2sh <- rio::import("workingData/data_M2sh.RDS")$pairwise %>%
dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
data_meContrasts_M2sh <- model_M2sh %>%
emmeans::emmeans(~ time_point | group,
epred = TRUE,
re_formula = NA,) %>%
emmeans::contrast(method = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::filter(contrast != "after - sensors")
# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_M2sh %>%
emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
emmeans::contrast(interaction = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::rename(contrast = time_point_revpairwise,
group = group_revpairwise) %>%
dplyr::filter(contrast != "after - sensors")
data_meContrasts_M2sh <- base::rbind(data_meContrasts_M2sh, interaction_contrast) %>%
dplyr::mutate(group = case_when(
group == "PD" ~ "PwPD",
group == "Control" ~ "Control",
group == "PD - Control" ~ "PwPD -\nControl"
)) %>%
base::merge(., robust_M2sh) %>%
dplyr::mutate(robust = factor(robust,
levels = c("not robust",
"robust")))
#bayestestR::p_direction(data_meContrasts_M2sh)
Combined
Expected Posteriors
# Generate expected predictions from the posterior
data_posterior_M2 <- rbind(data_posterior_M2s %>%
dplyr::mutate(sound = "/s/"),
data_posterior_M2sh %>%
dplyr::mutate(sound = "/ʃ/"))
plot_grandMean_M2 <- ggplot(data_posterior_M2,
aes(x = .epred, y = time_point,
fill = group)) +
stat_halfeye(alpha = .9) +
ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
labs(x = "Predicted M2 (kHz)", y = NULL,
fill = "Group",
title = "(a) Posterior Predictions",
subtitle = "Predicted M2 after controlling for\nspeaker age, sex, and articulation rate.") +
scale_y_discrete(limits = rev) +
theme_clean() +
facet_wrap(~sound, ncol = 1) +
theme(legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)) +
guides(fill = guide_legend(nrow = 1))
ME: Timepoint x Group
data_meContrasts_M2 <- rbind(data_meContrasts_M2s %>%
dplyr::mutate(sound = "/s/"),
data_meContrasts_M2sh %>%
dplyr::mutate(sound = "/ʃ/"))
#bayestestR::p_direction(data_meContrasts_M2)
plot_RQ1_M2 <- ggplot(
data_meContrasts_M2 %>%
dplyr::filter(contrast == "sensors - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of sensors effects (kHz)",
y = NULL,
title = "(b) Research Question 1",
subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
facet_wrap(~sound, ncol = 1) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ1_M2

plot_RQ2_M2 <- ggplot(
data_meContrasts_M2 %>%
dplyr::filter(contrast == "after - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of after-sensor\neffects (kHz)",
y = NULL,
title = "(c) Research Question 2",
subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
facet_wrap(~sound, ncol = 1) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ2_M2

# Combined plot
plot_M2 <- plot_grandMean_M2 + plot_RQ1_M2 + plot_RQ2_M2 +
patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect") +
plot_annotation(title = "Spectral Standard Deviation (M2)", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
theme = theme_clean()) &
theme(legend.position = "bottom")
plot_M2
ggsave(
plot = plot_M2,
filename = "Figures/Fig_M2.png",
height = 7,
width = 10,
unit = "in",
scale = .9,
bg = "white"
)

06. Intelligibility
Expected Posteriors
epsilon <- 1e-5
# Generate expected predictions from the posterior
data_posterior_Int <- model_Int %>%
tidybayes::epred_draws(
newdata = tidyr::expand_grid(
group = c("Control", "PD"),
time_point = c("before", "sensors", "after"),
sex = c("Male", "Female"),
age = mean(model_Int$data$age), # 66.91 yo
artic_rate = mean(model_Int$data$artic_rate), # 4.85 syl/s
trial_number = mean(model_Int$data$trial_number) # trial 9
),
re_formula = NA
) %>%
group_by(.draw, group, time_point) %>%
summarize(.epred = mean(.epred), .groups = "drop") %>%
dplyr::mutate(
group = factor(
group,
levels = c("Control", "PD"),
labels = c("Control", "PwPD")
),
#grouping = paste(sex, group, sep = " - "),
#grouping = factor(grouping,
# levels = c("Male - Control",
# "Male - PwPD",
# "Female - Control",
# "Female - PwPD")),
time_point = factor(
time_point,
levels = c("before", "sensors", "after"),
labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
),
.epred = (.epred - epsilon) / (1 - 2 * epsilon),
# Step 1 & 2: Reverse the offset and scaling
.epred = .epred * nrow(.) / ((nrow(.) - 1) + .5),
.epred = .epred * 100 # to turn it back to a scale of 0 - 100
)
plot_grandMean_Int <- ggplot(data_posterior_Int,
aes(x = .epred, y = time_point,
fill = group)) +
stat_halfeye(alpha = .9) +
ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
labs(x = "Predicted intelligibility rating (%)", y = NULL,
fill = "Group",
title = "(a) Posterior Predictions",
subtitle = "Predicted intelligibility rating after controlling\nfor speaker age, sex, articulation rate,\nand trial number.") +
scale_y_discrete(limits = rev) +
coord_cartesian(xlim = c(72,100)) +
theme_clean() +
theme(legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle),
#panel.border = element_rect(color = "grey", fill = NA)
) +
guides(fill = guide_legend(nrow = 1))
ME: Timepoint x Group
robust_Int <- rio::import("workingData/data_Int.RDS")$pairwise %>%
dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
epsilon <- 1e-5
data_meContrasts_Int <- model_Int %>%
emmeans::emmeans(~ time_point | group,
epred = TRUE,
re_formula = NA,) %>%
emmeans::contrast(method = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::mutate(
.value = (.value - epsilon) / (1 - 2 * epsilon),
# Step 1 & 2: Reverse the offset and scaling
.value = .value * nrow(.) / ((nrow(.) - 1) + .5),
.value = .value * 100
) %>%
dplyr::filter(contrast != "after - sensors")
# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_Int %>%
emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
emmeans::contrast(interaction = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::mutate(
.value = (.value - epsilon) / (1 - 2 * epsilon),
# Step 1 & 2: Reverse the offset and scaling
.value = .value * nrow(.) / ((nrow(.) - 1) + .5),
.value = .value * 100
) %>%
dplyr::rename(contrast = time_point_revpairwise,
group = group_revpairwise) %>%
dplyr::filter(contrast != "after - sensors")
data_meContrasts_Int <- base::rbind(data_meContrasts_Int, interaction_contrast) %>%
dplyr::mutate(group = case_when(
group == "PD" ~ "PwPD",
group == "Control" ~ "Control",
group == "PD - Control" ~ "PwPD -\nControl"
)) %>%
base::merge(., robust_Int) %>%
dplyr::mutate(robust = factor(robust,
levels = c("not robust",
"robust")))
plot_RQ1_Int <- ggplot(
data_meContrasts_Int %>%
dplyr::filter(contrast == "sensors - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
# Text annotation for the Control and PwPD distributions
annotate(
'text',
x = -.13*100, # Play around with the coordinates until you're satisfied
y = 3.3,
label = "Both Control and PwPD\nwere robustly less intelligbile\nwith EMA sensors on...",
hjust = 0,
size = 2,
alpha = .8,
color = "black"
) +
# Arrow to the Control distribution
annotate(
'curve',
x = -.095*100, # Play around with the coordinates until you're satisfied
y = 3.1,
xend = -.03*100,
yend = 2.96,
linewidth = .4,
curvature = 0.2,
arrow = arrow(length = unit(0.1, 'cm'), type = "closed"),
alpha = 1,
color = "darkgrey"
) +
# Arrow to the PwPD distribution
annotate(
'curve',
x = -.096*100, # Play around with the coordinates until you're satisfied
y = 3.1,
xend = -.065*100,
yend = 2.3,
linewidth = .4,
curvature = 0.2,
arrow = arrow(length = unit(0.1, 'cm'), type = "closed"),
alpha = 1,
color = "darkgrey"
) +
# Text for the contrast distribution
annotate(
'text',
x = -.07*100, # Play around with the coordinates until you're satisfied
y = 0.73,
label = "... but these effects\nwere robustly different\nbetween the groups.",
hjust = 1,
size = 2,
alpha = .8,
color = "black"
) +
# Arrow to the contrast distribution
annotate(
'curve',
x = -.065*100, # Play around with the coordinates until you're satisfied
y = 0.73,
xend = -.045*100,
yend = .95,
linewidth = .4,
curvature = 0.2,
arrow = arrow(length = unit(0.1, 'cm'), type = "closed"),
alpha = 1,
color = "darkgrey"
) +
labs(
x = "Average marginal effect of sensors effects (%)",
y = NULL,
title = "(b) Research Question 1",
subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ1_Int

plot_RQ2_Int <- ggplot(
data_meContrasts_Int %>%
dplyr::filter(contrast == "after - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of after-sensor\neffects (%)",
y = NULL,
title = "(c) Research Question 2",
subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ2_Int

# Combined plot
plot_Int <- plot_grandMean_Int + plot_RQ1_Int + plot_RQ2_Int +
patchwork::plot_layout(ncol = 3, heights = c(1), guides = "collect") +
plot_annotation(title = "Intelligibility", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
theme = theme_clean()) &
theme(legend.position = "bottom")
plot_Int
ggsave(
plot = plot_Int,
filename = "Figures/Fig_Int.png",
height = 6,
width = 10,
unit = "in",
scale = .9,
bg = "white"
)

07. Naturalness
Expected Posteriors
epsilon <- 1e-5
# Generate expected predictions from the posterior
data_posterior_Nat <- model_Nat %>%
tidybayes::epred_draws(
newdata = tidyr::expand_grid(
group = c("Control", "PD"),
time_point = c("before", "sensors", "after"),
sex = c("Male", "Female"),
age = mean(model_Nat$data$age), # 66.91 yo
artic_rate = mean(model_Nat$data$artic_rate), # 4.85 syl/s
trial_number = mean(model_Nat$data$trial_number) # trial 9
),
re_formula = NA
) %>%
group_by(.draw, group, time_point) %>%
summarize(.epred = mean(.epred), .groups = "drop") %>%
dplyr::mutate(
group = factor(
group,
levels = c("Control", "PD"),
labels = c("Control", "PwPD")
),
#grouping = paste(sex, group, sep = " - "),
#grouping = factor(grouping,
# levels = c("Male - Control",
# "Male - PwPD",
# "Female - Control",
# "Female - PwPD")),
time_point = factor(
time_point,
levels = c("before", "sensors", "after"),
labels = c("Before\nSensors", "With\nSensors", "After\nSensors")
),
.epred = (.epred - epsilon) / (1 - 2 * epsilon),
# Step 1 & 2: Reverse the offset and scaling
.epred = .epred * nrow(.) / ((nrow(.) - 1) + .5),
.epred = .epred * 100
)
plot_grandMean_Nat <- ggplot(data_posterior_Nat,
aes(x = .epred, y = time_point,
fill = group)) +
stat_halfeye(alpha = .9) +
ggokabeito::scale_fill_okabe_ito(order = c(2, 1)) +
labs(x = "Predicted naturalness rating (%)", y = NULL,
fill = "Group",
title = "(a) Posterior Predictions",
subtitle = "Predicted naturalness rating after controlling\nfor speaker age, sex, articulation rate,\nand trial number.") +
scale_y_discrete(limits = rev) +
coord_cartesian(xlim = c(0,100)) +
theme_clean() +
theme(legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)) +
guides(fill = guide_legend(nrow = 1))
ME: Timepoint x Group
robust_Nat <- rio::import("workingData/data_Nat.RDS")$pairwise %>%
dplyr::select(contrast, group, robust)
Warning: Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
epsilon <- 1e-5
data_meContrasts_Nat <- model_Nat %>%
emmeans::emmeans(~ time_point | group,
epred = TRUE,
re_formula = NA,) %>%
emmeans::contrast(method = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::mutate(
.value = (.value - epsilon) / (1 - 2 * epsilon),
# Step 1 & 2: Reverse the offset and scaling
.value = .value * nrow(.) / ((nrow(.) - 1) + .5),
.value = .value * 100
) %>%
dplyr::filter(contrast != "after - sensors")
# Compute the interaction contrast (difference in contrasts between groups)
interaction_contrast <- model_Nat %>%
emmeans::emmeans(~ time_point * group, epred = TRUE, re_formula = NA) %>%
emmeans::contrast(interaction = "revpairwise") %>%
gather_emmeans_draws() %>%
dplyr::mutate(
.value = (.value - epsilon) / (1 - 2 * epsilon),
# Step 1 & 2: Reverse the offset and scaling
.value = .value * nrow(.) / ((nrow(.) - 1) + .5),
.value = .value * 100
) %>%
dplyr::rename(contrast = time_point_revpairwise,
group = group_revpairwise) %>%
dplyr::filter(contrast != "after - sensors")
data_meContrasts_Nat <- base::rbind(data_meContrasts_Nat, interaction_contrast) %>%
dplyr::mutate(group = case_when(
group == "PD" ~ "PwPD",
group == "Control" ~ "Control",
group == "PD - Control" ~ "PwPD -\nControl"
)) %>%
base::merge(., robust_Nat) %>%
dplyr::mutate(robust = factor(robust,
levels = c("not robust",
"robust")))
#bayestestR::p_direction(data_meContrasts_Nat)
plot_RQ1_Nat <- ggplot(
data_meContrasts_Nat %>%
dplyr::filter(contrast == "sensors - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of sensors effects (%)",
y = NULL,
title = "(b) Research Question 1",
subtitle = "Sensor effect (With Sensors - Before Sensors)\nper group and the effect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ1_Nat

plot_RQ2_Nat <- ggplot(
data_meContrasts_Nat %>%
dplyr::filter(contrast == "after - before"),
aes(x = .value, y = group, fill = robust)
) +
geom_vline(xintercept = 0, alpha = .3) +
stat_halfeye(alpha = .9) +
scale_fill_manual(values = c("#E3B5CF", "#CC79A7"),
drop = FALSE) +
labs(
x = "Average marginal effect of after-sensors\neffects (%)",
y = NULL,
title = "(c) Research Question 2",
subtitle = "After-sensor effect (After Sensors -\nBefore Sensors) per group and the\neffect contrast between groups.",
fill = "Robust at 95% HPD Interval & pd"
) +
scale_y_discrete(limits = rev) +
theme_clean() +
theme(
legend.position = "bottom",
axis.title = element_text(size = textSize_axisTitle),
plot.title = element_text(size = textSize_plotTitle),
plot.subtitle = element_text(size = textSize_plotSubtitle)
)
plot_RQ2_Nat

# Combined plot
plot_Nat <- plot_grandMean_Nat + plot_RQ1_Nat + plot_RQ2_Nat +
patchwork::plot_layout(ncol = 3,
heights = c(1),
guides = "collect") +
plot_annotation(title = "Naturalness",
theme = theme_clean()) &
theme(legend.position = "bottom")
plot_Nat
ggsave(
plot = plot_Nat,
filename = "Figures/Fig_Nat.png",
height = 6,
width = 10,
unit = "in",
scale = .9,
bg = "white"
)

S01. Individual Variability
workingData_articRate <- base::readRDS(file = "workingData/data_articRate.RDS")
workingData_AAVS <- base::readRDS(file = "workingData/data_AAVS.RDS")
workingData_M1s <- base::readRDS(file = "workingData/data_M1s.RDS")
workingData_M1sh <- base::readRDS(file = "workingData/data_M1sh.RDS")
workingData_M2s <- base::readRDS(file = "workingData/data_M2s.RDS")
workingData_M2sh <- base::readRDS(file = "workingData/data_M2sh.RDS")
workingData_Int <- base::readRDS(file = "workingData/data_Int.RDS")
workingData_Nat <- base::readRDS(file = "workingData/data_Nat.RDS")
allData <- bind_rows(
workingData_articRate$modelData %>%
dplyr::mutate(measure = "Articulation Rate") %>%
dplyr::rename(value = articRate),
workingData_AAVS$modelData %>%
dplyr::mutate(measure = "AAVS") %>%
dplyr::rename(value = AAVS),
workingData_M1s$modelData %>%
dplyr::mutate(measure = "M1 for /s/") %>%
dplyr::rename(value = M1s),
workingData_M2s$modelData %>%
dplyr::mutate(measure = "M2 for /s/") %>%
dplyr::rename(value = M2s),
workingData_M1sh$modelData %>%
dplyr::mutate(measure = "M1 for /ʃ/") %>%
dplyr::rename(value = M1sh),
workingData_M2sh$modelData %>%
dplyr::mutate(measure = "M2 for /ʃ/") %>%
dplyr::rename(value = M2sh),
workingData_Int$modelData %>%
dplyr::mutate(measure = "Intelligibility",
Int = Int*100) %>%
dplyr::rename(value = Int),
workingData_Nat$modelData %>%
dplyr::mutate(measure = "Naturalness",
Nat = Nat*100) %>%
dplyr::rename(value = Nat)
) %>%
dplyr::mutate(time_point = factor(time_point,
levels = c("before",
"sensors",
"after"),
labels = c("Before\nSensors",
"With\nSensors",
"After\nSensors")),
measure = factor(measure,
levels = c("Articulation Rate",
"AAVS",
"M1 for /s/",
"M2 for /s/",
"M1 for /ʃ/",
"M2 for /ʃ/",
"Intelligibility",
"Naturalness"),
labels = c("Articulation Rate (syl/s)",
"AAVS (mel²)",
"M1 for /s/ (kHz)",
"M2 for /s/ (kHz)",
"M1 for /ʃ/ (kHz)",
"M2 for /ʃ/ (kHz)",
"Intelligibility (%)",
"Naturalness (%)")),
group = factor(group,
levels = c("Control",
"PD"),
labels = c("Control",
"PwPD")),
grouping = paste(sex, group, sep = " - "),
grouping = factor(grouping,
levels = c("Male - Control",
"Male - PwPD",
"Female - Control",
"Female - PwPD"))) %>%
dplyr::group_by(measure, speaker_id, group, sex, grouping, age, time_point) %>%
dplyr::summarise(value = mean(value)) %>%
dplyr::ungroup()
`summarise()` has grouped output by 'measure', 'speaker_id', 'group', 'sex', 'grouping', 'age'. You can override using the `.groups` argument.
plotData <- bind_rows(
allData %>%
dplyr::mutate(plot = "All Data"),
allData %>%
dplyr::filter(time_point != "After\nSensors") %>%
dplyr::mutate(plot = "Sensor Effects"),
allData %>%
dplyr::filter(time_point != "With\nSensors") %>%
dplyr::mutate(plot = "After-Sensor Effects"),
) %>%
dplyr::mutate(plot = factor(plot,
levels = c("All Data",
"Sensor Effects",
"After-Sensor Effects"),
labels = c("All Data",
"Sensor Effects",
"After-Sensor\nEffects"))) %>%
dplyr::filter(plot != "All Data")
plot_rawData_sensorEffects <- plotData %>%
dplyr::filter(plot == "Sensor Effects") %>%
ggplot() +
aes(x = time_point, y = value, color = group) +
geom_line(aes(group = speaker_id), alpha = .3) +
geom_line(
data = plotData %>%
dplyr::filter(plot == "Sensor Effects") %>%
dplyr::group_by(measure, group, sex, time_point, plot) %>%
dplyr::summarise(value = mean(value)),
aes(group = group),
alpha = .8,
linewidth = 1.5
) +
#geom_point(aes(shape = sex)) +
ggokabeito::scale_color_okabe_ito(order = c(2,1)) +
facet_grid(measure ~ sex, scales = "free", switch = "y") +
labs(x = NULL,
y = NULL,
color = "Group",
shape = "Sex",
title = "Sensor Effects") +
scale_x_discrete(expand=expansion(c(.35,.35))) +
theme_clean() &
theme(panel.border = element_rect(fill = NA, color = "black"),
strip.background = element_rect(fill = "white", color = NA),
strip.placement = "outside",
strip.text.y.left = element_text(angle = 0, face="plain", hjust = 1),)
`summarise()` has grouped output by 'measure', 'group', 'sex', 'time_point'. You can override using the `.groups` argument.
plot_rawData_sensorEffects

plot_rawData_afterSensorEffects <- plotData %>%
dplyr::filter(plot == "After-Sensor\nEffects") %>%
ggplot() +
aes(x = time_point, y = value, color = group) +
geom_line(aes(group = speaker_id), alpha = .3) +
geom_line(
data = plotData %>%
dplyr::filter(plot == "After-Sensor\nEffects") %>%
dplyr::group_by(measure, group, sex, time_point, plot) %>%
dplyr::summarise(value = mean(value)),
aes(group = group),
alpha = .8,
linewidth = 1.5
) +
#geom_point(aes(shape = sex)) +
ggokabeito::scale_color_okabe_ito(order = c(2,1)) +
facet_grid(measure ~ sex, scales = "free") +
labs(x = NULL,
y = NULL,
color = "Group",
shape = "Sex",
title = "After-Sensor Effects") +
scale_x_discrete(expand=expansion(c(.35,.35))) +
theme_clean() &
theme(panel.border = element_rect(fill = NA, color = "black"),
#strip.background = element_rect(fill = "white", color = NA),
strip.placement = "outside",
#strip.text.y.left = element_text(angle = 0, face="plain", hjust = 1),
strip.background = element_blank(),
strip.text.y. = element_blank())
`summarise()` has grouped output by 'measure', 'group', 'sex', 'time_point'. You can override using the `.groups` argument.
plot_rawData_afterSensorEffects
plot_rawData <- plot_rawData_sensorEffects + plot_rawData_afterSensorEffects +
patchwork::plot_layout(ncol = 2, #heights = c(1),
guides = "collect") +
plot_annotation(title = "Raw Data", #subtitle = "Predicted intelligibility ratings across group/severity and speaking conditions.",
theme = theme_clean()) &
theme(
legend.position = "right",
strip.background.right = element_blank(),
strip.text.y.right = element_blank()
)
ggsave(
plot = plot_rawData,
filename = "Figures/SupFig_rawData.png",
height = 10,
width = 9,
unit = "in",
scale = .9,
bg = "white"
)

LS0tCnRpdGxlOiAiVm93ZWwgQXJ0aWMgaW4gUEQ6IFBsb3RzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIFBhY2thZ2VzCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3JlcGVsKQpsaWJyYXJ5KGV4dHJhRGlzdHIpICAgIyBpbnN0YWxsLnBhY2thZ2VzKCJleHRyYURpc3RyIikKbGlicmFyeShIREludGVydmFsKSAgICMgaW5zdGFsbC5wYWNrYWdlcygiSERBUGVydmFsIikKbGlicmFyeSh0aWR5YmF5ZXMpICAgICMgaW5zdGFsbC5wYWNrYWdlcygidGlkeWJheWVzIikKbGlicmFyeShiYXllc3Bsb3QpICAgICMgaW5zdGFsbC5wYWNrYWdlcygiYmF5ZXNwbG90IikKbGlicmFyeShtb2RlbHIpCmxpYnJhcnkoYnJvb20ubWl4ZWQpICAjIGluc3RhbGwucGFja2FnZXMoImJyb29tLm1peGVkIikKbGlicmFyeShicm1zKSAgICAgICAgICMgaW5zdGFsbC5wYWNrYWdlcygiYnJtcyIpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGdnb2thYmVpdG8pICAgIyBpbnN0YWxsLnBhY2thZ2VzKCJnZ29rYWJlaXRvIikKdGhlbWVfc2V0KHRoZW1lX21pbmltYWwoKSkKCiMgQ3JlYXRpbmcgYSB0aGVtZSBmdW5jdGlvbiB1c2VkIGZvciB2aXN1YWxpemF0aW9ucwp0aGVtZV9jbGVhbiA8LSBmdW5jdGlvbigpIHsKICB0aGVtZV9taW5pbWFsKGJhc2VfZmFtaWx5ID0gIkFyaWFsIikgKwogICAgdGhlbWUocGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksCiAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLAogICAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gcmVsKDEpLCBoanVzdCA9IDApLAogICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk4MCIsIGNvbG9yID0gTkEpLAogICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpKQp9CmBgYAoKIyBMb2FkaW5nIHRoZSBtb2RlbHMKYGBge3J9Cm1vZGVsX0ludCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAiTW9kZWxzL2JybXNfSW50LnJkcyIpCm1vZGVsX05hdCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAiTW9kZWxzL2JybXNfTmF0LnJkcyIpCm1vZGVsX2FydGljUmF0ZSA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAiTW9kZWxzL2JybXNfYXJ0aWNSYXRlLnJkcyIpCm1vZGVsX0FBVlMgPC0gYmFzZTo6cmVhZFJEUyhmaWxlID0gIk1vZGVscy9icm1zX0FBVlMucmRzIikKbW9kZWxfTTFzIDwtIGJhc2U6OnJlYWRSRFMoZmlsZSA9ICJNb2RlbHMvYnJtc19NMXMucmRzIikKbW9kZWxfTTFzaCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAiTW9kZWxzL2JybXNfTTFzaC5yZHMiKQptb2RlbF9NMnMgPC0gYmFzZTo6cmVhZFJEUyhmaWxlID0gIk1vZGVscy9icm1zX00ycy5yZHMiKQptb2RlbF9NMnNoIDwtIGJhc2U6OnJlYWRSRFMoZmlsZSA9ICJNb2RlbHMvYnJtc19NMnNoLnJkcyIpCmBgYAoKIyBGb3JtYXR0aW5nIGluZm8KYGBge3J9CnRleHRTaXplX3Bsb3RUaXRsZSA8LSA5CnRleHRTaXplX3Bsb3RTdWJ0aXRsZSA8LSA5CnRleHRTaXplX2F4aXNUaXRsZSA8LSA5CmBgYAoKIyAwMS4gUmVsaWFiaWxpdHkKYGBge3J9CndvcmtpbmdEYXRhX0ludCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9JbnQuUkRTIikKd29ya2luZ0RhdGFfTmF0IDwtIGJhc2U6OnJlYWRSRFMoZmlsZSA9ICJ3b3JraW5nRGF0YS9kYXRhX05hdC5SRFMiKQoKaW50ZXJSZWxfcGxvdERhdGEgPC0gcmJpbmQoCiAgd29ya2luZ0RhdGFfSW50JGRhdGEgJT4lCiAgICBkcGx5cjo6c2VsZWN0KGMoCiAgICAgIGdvcmlsbGFfaWQsCiAgICAgIHNwZWFrZXJfaWQsCiAgICAgIGBUaW1lIFBvaW50YCA9IHRpbWVfcG9pbnQsCiAgICAgIEdyb3VwID0gZ3JvdXAsCiAgICAgIFNleCA9IHNleCwKICAgICAgYWdlLAogICAgICByYXRpbmcKICAgICkKICAgICkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKAogICAgICBNZWFzdXJlID0gIkludGVsbGlnaWJpbGl0eSIKICAgICksCiAgd29ya2luZ0RhdGFfTmF0JGRhdGEgJT4lCiAgICBkcGx5cjo6c2VsZWN0KGMoCiAgICAgIGdvcmlsbGFfaWQsCiAgICAgIHNwZWFrZXJfaWQsCiAgICAgIGBUaW1lIFBvaW50YCA9IHRpbWVfcG9pbnQsCiAgICAgIEdyb3VwID0gZ3JvdXAsCiAgICAgIFNleCA9IHNleCwKICAgICAgYWdlLAogICAgICByYXRpbmcKICAgICkKICAgICkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKAogICAgICBNZWFzdXJlID0gIk5hdHVyYWxuZXNzIgogICAgKQopICU+JQogIGRwbHlyOjpmaWx0ZXIoZ29yaWxsYV9pZCAhPSAiMTAyMzc4NTEiKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoc3BlYWtlcl9pZCwgYFRpbWUgUG9pbnRgLCBHcm91cCwgU2V4LCBhZ2UsIE1lYXN1cmUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoTSA9IG1lYW4ocmF0aW5nKSwKICAgICAgICAgICAgICAgICAgIHNkID0gc2QocmF0aW5nKSkgJT4lCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUKICBkcGx5cjo6bXV0YXRlKGBUaW1lIFBvaW50YCA9IGZhY3RvcihgVGltZSBQb2ludGAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiYmVmb3JlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZW5zb3JzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZnRlciIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkJlZm9yZSBTZW5zb3JzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXaXRoIFNlbnNvcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFmdGVyIFNlbnNvcnMiKSksCiAgICAgICAgICAgICAgICBNZWFzdXJlID0gZmFjdG9yKE1lYXN1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkludGVsbGlnaWJpbGl0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5hdHVyYWxuZXNzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkludGVsbGlnaWJpbGl0eSBSYXRpbmdzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmF0dXJhbG5lc3MgUmF0aW5ncyIpKSwKICAgICAgICAgICAgICAgIEdyb3VwID0gZmFjdG9yKEdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQRCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQd1BEIikpKQoKaW50ZXJSZWxfcGxvdCA8LSBpbnRlclJlbF9wbG90RGF0YSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKAogICAgeCA9IE0sCiAgICB5ID0gc2QsCiAgICBjb2xvciA9IEdyb3VwLAogICAgc2hhcGUgPSBgVGltZSBQb2ludGAKICApICsKICBnZW9tX3BvaW50KCkgKwogIGZhY2V0X3dyYXAofk1lYXN1cmUpICsKICBsYWJzKHggPSAiQXZlcmFnZSBSYXRpbmcgKE1lYW4pIiwKICAgICAgIHkgPSAiUmF0aW5nIFZhcmlhYmlsaXR5IChzZCkiLAogICAgICAgdGl0bGUgPSAiSW50ZXItbGlzdGVuZXIgUmVsaWFiaWxpdHkiLAogICAgICAgI3N1YnRpdGxlID0gIlRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgcmF0aW5ncyBhY3Jvc3Mgc3BlYWtlcnMgYW5kIHRpbWUgcG9pbnRzLiIKICAgICAgICkgKwogIGdnb2thYmVpdG86OnNjYWxlX2NvbG9yX29rYWJlX2l0byhvcmRlciA9IGMoMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIzUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICM0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKSkgKwogIGdndGhlbWVzOjp0aGVtZV9jbGVhbigpICYKICB0aGVtZSgKICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIHNpemUgPSAxMiksCiAgICBzdHJpcC50ZXh0LnkgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwKSwKICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICNwYW5lbC5tYXJnaW49dW5pdCguMDUsICJsaW5lcyIpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgc2l6ZSA9IDEpLCAKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEpLAogICAgI3BhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgc2l6ZSA9IDEpLCAKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgbGVnZW5kLmJveD0idmVydGljYWwiLAogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSBOQSksCiAgICBhc3BlY3QucmF0aW8gPSAxKQoKaW50ZXJSZWxfcGxvdAoKZ2dzYXZlKHBsb3QgPSBpbnRlclJlbF9wbG90LAogICAgICAgZmlsZSA9ICJGaWd1cmVzL0ZpZ19JbnRlci1MaXN0ZW5lciBSZWxpYWJpbGl0eS5wbmciLAogICAgICAgaGVpZ2h0ID0gNSwKICAgICAgIHdpZHRoID0gNi41LAogICAgICAgdW5pdHMgPSAiaW4iLAogICAgICAgc2NhbGUgPSAxLAogICAgICAgYmcgPSAid2hpdGUiKQpgYGAKCiMgMDIuIEFydGljIFJhdGUKIyMgRXhwZWN0ZWQgUG9zdGVyaW9ycwpgYGB7cn0KIyBHZW5lcmF0ZSBleHBlY3RlZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKZGF0YV9wb3N0ZXJpb3JfYXJ0aWNSYXRlIDwtIG1vZGVsX2FydGljUmF0ZSAlPiUKICB0aWR5YmF5ZXM6OmVwcmVkX2RyYXdzKAogICAgbmV3ZGF0YSA9IHRpZHlyOjpleHBhbmRfZ3JpZCgKICAgICAgZ3JvdXAgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIHRpbWVfcG9pbnQgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBzZXggPSBjKCJNYWxlIiwgIkZlbWFsZSIpLAogICAgICBhZ2UgPSA2Ni44OCwKICAgICksCiAgICByZV9mb3JtdWxhID0gTkEKICApICU+JQogIGdyb3VwX2J5KC5kcmF3LCBncm91cCwgdGltZV9wb2ludCkgJT4lCiAgc3VtbWFyaXplKC5lcHJlZCA9IG1lYW4oLmVwcmVkKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIGdyb3VwID0gZmFjdG9yKAogICAgICBncm91cCwKICAgICAgbGV2ZWxzID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwgIlB3UEQiKQogICAgKSwKICAgICNncm91cGluZyA9IHBhc3RlKHNleCwgZ3JvdXAsIHNlcCA9ICIgLSAiKSwKICAgICNncm91cGluZyA9IGZhY3Rvcihncm91cGluZywKICAgICMgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFsZSAtIFB3UEQiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIFB3UEQiKSksCiAgICB0aW1lX3BvaW50ID0gZmFjdG9yKAogICAgICB0aW1lX3BvaW50LAogICAgICBsZXZlbHMgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBsYWJlbHMgPSBjKCJCZWZvcmVcblNlbnNvcnMiLCAiV2l0aFxuU2Vuc29ycyIsICJBZnRlclxuU2Vuc29ycyIpCiAgICApCiAgKQoKcGxvdF9ncmFuZE1lYW5fYXJ0aWNSYXRlIDwtIGdncGxvdChkYXRhX3Bvc3Rlcmlvcl9hcnRpY1JhdGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gLmVwcmVkLCB5ID0gdGltZV9wb2ludCwgZmlsbCA9IGdyb3VwKSkgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgZ2dva2FiZWl0bzo6c2NhbGVfZmlsbF9va2FiZV9pdG8ob3JkZXIgPSBjKDIsIDEpKSArCiAgbGFicyh4ID0gIlByZWRpY3RlZCBhcnRpY3VsYXRpb24gcmF0ZSAoc3lsL3MpIiwgeSA9IE5VTEwsCiAgICAgICBmaWxsID0gIkdyb3VwIiwKICAgICAgIHRpdGxlID0gIihhKSBQb3N0ZXJpb3IgUHJlZGljdGlvbnMiLAogICAgICAgc3VidGl0bGUgPSAiUHJlZGljdGVkIGFydGljdWxhdGlvbiByYXRlIGFmdGVyXG5jb250cm9sbGluZyBmb3Igc3BlYWtlciBhZ2UgYW5kIHNleC4iKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICAjZmFjZXRfZ3JpZChzZXh+LikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpLAogICAgICAgICNwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiZ3JleSIsIGZpbGwgPSBOQSkKICAgICAgICApICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpCmBgYAoKIyMgTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpyb2J1c3RfYXJ0aWNSYXRlIDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX2FydGljUmF0ZS5SRFMiKSRwYWlyd2lzZSAlPiUKICBkcGx5cjo6c2VsZWN0KGNvbnRyYXN0LCBncm91cCwgcm9idXN0KQoKZGF0YV9tZUNvbnRyYXN0c19hcnRpY1JhdGUgPC0gbW9kZWxfYXJ0aWNSYXRlICU+JQogIGVtbWVhbnM6OmVtbWVhbnMoIH4gdGltZV9wb2ludCB8IGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSwgKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfYXJ0aWNSYXRlICU+JQogIGVtbWVhbnM6OmVtbWVhbnMoIH4gdGltZV9wb2ludCAqIGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QoaW50ZXJhY3Rpb24gPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpyZW5hbWUoY29udHJhc3QgPSB0aW1lX3BvaW50X3JldnBhaXJ3aXNlLCBncm91cCA9IGdyb3VwX3JldnBhaXJ3aXNlKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKZGF0YV9tZUNvbnRyYXN0c19hcnRpY1JhdGUgPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19hcnRpY1JhdGUsIGludGVyYWN0aW9uX2NvbnRyYXN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgZ3JvdXAgPT0gIlBEIiB+ICJQd1BEIiwKICAgIGdyb3VwID09ICJDb250cm9sIiB+ICJDb250cm9sIiwKICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICApKSAlPiUKICBiYXNlOjptZXJnZSguLCByb2J1c3RfYXJ0aWNSYXRlKQoKcGxvdF9SUTFfYXJ0aWNSYXRlIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX2FydGljUmF0ZSAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgPT0gInNlbnNvcnMgLSBiZWZvcmUiKSwKICAgIGFlcyh4ID0gLnZhbHVlLCB5ID0gZ3JvdXAsIGZpbGwgPSByb2J1c3QpCikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGFscGhhID0gLjMpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFM0I1Q0YiLCAiI0NDNzlBNyIpLAogICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpICsKICBsYWJzKAogICAgeCA9ICJBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdCBvZiBzZW5zb3JzIGVmZmVjdHMgKHN5bC9zKSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihiKSBSZXNlYXJjaCBRdWVzdGlvbiAxIiwKICAgIHN1YnRpdGxlID0gIlNlbnNvciBlZmZlY3QgKFdpdGggU2Vuc29ycyAtIEJlZm9yZSBTZW5zb3JzKVxucGVyIGdyb3VwIGFuZCB0aGUgZWZmZWN0IGNvbnRyYXN0IGJldHdlZW4gZ3JvdXBzLiIsCiAgICBmaWxsID0gIlJvYnVzdCBhdCA5NSUgSFBEIEludGVydmFsICYgcGQiCiAgKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpCiAgKQoKcGxvdF9SUTFfYXJ0aWNSYXRlCgpwbG90X1JRMl9hcnRpY1JhdGUgPC0gZ2dwbG90KAogIGRhdGFfbWVDb250cmFzdHNfYXJ0aWNSYXRlICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAiYWZ0ZXIgLSBiZWZvcmUiKSwKICAgIGFlcyh4ID0gLnZhbHVlLCB5ID0gZ3JvdXAsIGZpbGwgPSByb2J1c3QpCikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGFscGhhID0gLjMpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFM0I1Q0YiLCAiI0NDNzlBNyIpLAogICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpICsKICBsYWJzKAogICAgeCA9ICJBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdCBvZiBhZnRlci1zZW5zb3JcbmVmZmVjdHMgKHN5bC9zKSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihjKSBSZXNlYXJjaCBRdWVzdGlvbiAyIiwKICAgIHN1YnRpdGxlID0gIkFmdGVyLXNlbnNvciBlZmZlY3QgKEFmdGVyIFNlbnNvcnMgLVxuQmVmb3JlIFNlbnNvcnMpIHBlciBncm91cCBhbmQgdGhlXG5lZmZlY3QgY29udHJhc3QgYmV0d2VlbiBncm91cHMuIiwKICAgIGZpbGwgPSAiUm9idXN0IGF0IDk1JSBIUEQgSW50ZXJ2YWwgJiBwZCIKICApICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIHRoZW1lX2NsZWFuKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RTdWJ0aXRsZSkKICApCgpwbG90X1JRMl9hcnRpY1JhdGUKCiMgQ29tYmluZWQgcGxvdApwbG90X2FydGljUmF0ZSA8LSAgcGxvdF9ncmFuZE1lYW5fYXJ0aWNSYXRlICsgcGxvdF9SUTFfYXJ0aWNSYXRlICsgcGxvdF9SUTJfYXJ0aWNSYXRlICsKICBwYXRjaHdvcms6OnBsb3RfbGF5b3V0KG5jb2wgPSAzLCBoZWlnaHRzID0gYygxKSwgZ3VpZGVzID0gImNvbGxlY3QiCiAgICAgICAgICAgICAgICAgICAgICAgICApICsKICBwbG90X2Fubm90YXRpb24odGl0bGUgPSAiQXJ0aWN1bGF0aW9uIFJhdGUiLCAjc3VidGl0bGUgPSAiUHJlZGljdGVkIGludGVsbGlnaWJpbGl0eSByYXRpbmdzIGFjcm9zcyBncm91cC9zZXZlcml0eSBhbmQgc3BlYWtpbmcgY29uZGl0aW9ucy4iLAogICAgICAgICAgICAgICAgICB0aGVtZSA9IHRoZW1lX2NsZWFuKCkpICYKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKcGxvdF9hcnRpY1JhdGUKCmdnc2F2ZSgKICBwbG90ID0gcGxvdF9hcnRpY1JhdGUsCiAgZmlsZW5hbWUgPSAiRmlndXJlcy9GaWdfYXJ0aWNSYXRlLnBuZyIsCiAgaGVpZ2h0ID0gNiwKICB3aWR0aCA9IDEwLAogIHVuaXQgPSAiaW4iLAogIHNjYWxlID0gLjksCiAgYmcgPSAid2hpdGUiCikKCmBgYAoKIyAwMy4gQUFWUwojIyBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQojIEdlbmVyYXRlIGV4cGVjdGVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHBvc3RlcmlvcgpkYXRhX3Bvc3Rlcmlvcl9BQVZTIDwtIG1vZGVsX0FBVlMgJT4lCiAgdGlkeWJheWVzOjplcHJlZF9kcmF3cygKICAgIG5ld2RhdGEgPSB0aWR5cjo6ZXhwYW5kX2dyaWQoCiAgICAgIGdyb3VwID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICB0aW1lX3BvaW50ID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgc2V4ID0gYygiTWFsZSIsICJGZW1hbGUiKSwKICAgICAgYWdlID0gbWVhbihtb2RlbF9BQVZTJGRhdGEkYWdlKSwKICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfQUFWUyRkYXRhJGFydGljX3JhdGUpLAogICAgKSwKICAgIHJlX2Zvcm11bGEgPSBOQQogICkgJT4lCiAgZ3JvdXBfYnkoLmRyYXcsIGdyb3VwLCB0aW1lX3BvaW50KSAlPiUKICBzdW1tYXJpemUoLmVwcmVkID0gbWVhbiguZXByZWQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBkcGx5cjo6bXV0YXRlKAogICAgZ3JvdXAgPSBmYWN0b3IoCiAgICAgIGdyb3VwLAogICAgICBsZXZlbHMgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIGxhYmVscyA9IGMoIkNvbnRyb2wiLCAiUHdQRCIpCiAgICApLAogICAgI2dyb3VwaW5nID0gcGFzdGUoc2V4LCBncm91cCwgc2VwID0gIiAtICIpLAogICAgI2dyb3VwaW5nID0gZmFjdG9yKGdyb3VwaW5nLAogICAgIyAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWxlIC0gUHdQRCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gUHdQRCIpKSwKICAgIHRpbWVfcG9pbnQgPSBmYWN0b3IoCiAgICAgIHRpbWVfcG9pbnQsCiAgICAgIGxldmVscyA9IGMoImJlZm9yZSIsICJzZW5zb3JzIiwgImFmdGVyIiksCiAgICAgIGxhYmVscyA9IGMoIkJlZm9yZVxuU2Vuc29ycyIsICJXaXRoXG5TZW5zb3JzIiwgIkFmdGVyXG5TZW5zb3JzIikKICAgICkKICApCgpwbG90X2dyYW5kTWVhbl9BQVZTIDwtIGdncGxvdChkYXRhX3Bvc3Rlcmlvcl9BQVZTLCBhZXMoeCA9IC5lcHJlZCwgeSA9IHRpbWVfcG9pbnQsIGZpbGwgPSBncm91cCkpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIGdnb2thYmVpdG86OnNjYWxlX2ZpbGxfb2thYmVfaXRvKG9yZGVyID0gYygyLCAxKSkgKwogIGxhYnMoeCA9ICJQcmVkaWN0ZWQgQUFWUyAobWVswrIpIiwgeSA9IE5VTEwsCiAgICAgICBmaWxsID0gIkdyb3VwIiwKICAgICAgIHRpdGxlID0gIihhKSBQb3N0ZXJpb3IgUHJlZGljdGlvbnMiLAogICAgICAgc3VidGl0bGUgPSAiUHJlZGljdGVkIEFBVlMgYWZ0ZXIgY29udHJvbGxpbmcgZm9yXG5zcGVha2VyIGFnZSwgc2V4LCBhbmQgYXJ0aWN1bGF0aW9uIHJhdGUuIikgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgI2Nvb3JkX2NhcnRlc2lhbih4bGltID0gYyguNjUsMSkpICsKICB0aGVtZV9jbGVhbigpICsKICAjZmFjZXRfZ3JpZChzZXh+LikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpLAogICAgICAgICNwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiZ3JleSIsIGZpbGwgPSBOQSkKICAgICAgICApICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpCnBsb3RfZ3JhbmRNZWFuX0FBVlMKYGBgCgojIyBNRTogVGltZXBvaW50IHggR3JvdXAKYGBge3J9CnJvYnVzdF9BQVZTIDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX0FBVlMuUkRTIikkcGFpcndpc2UgJT4lCiAgZHBseXI6OnNlbGVjdChjb250cmFzdCwgZ3JvdXAsIHJvYnVzdCkKCmRhdGFfbWVDb250cmFzdHNfQUFWUyA8LSBtb2RlbF9BQVZTICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50IHwgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICBlcHJlZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICByZV9mb3JtdWxhID0gTkEsKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpICAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgICBncm91cCA9PSAiUEQiIH4gIlB3UEQiLAogICAgICBncm91cCA9PSAiQ29udHJvbCIgfiAiQ29udHJvbCIKICAgICkpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfQUFWUyAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCAqIGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QoaW50ZXJhY3Rpb24gPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpyZW5hbWUoY29udHJhc3QgPSB0aW1lX3BvaW50X3JldnBhaXJ3aXNlLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBncm91cF9yZXZwYWlyd2lzZSkgJT4lCiAgZHBseXI6OmZpbHRlcihjb250cmFzdCAhPSAiYWZ0ZXIgLSBzZW5zb3JzIikgICU+JQogIGRwbHlyOjptdXRhdGUoZ3JvdXAgPSBjYXNlX3doZW4oCiAgICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICAgICkpCgpkYXRhX21lQ29udHJhc3RzX0FBVlMgPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19BQVZTLCBpbnRlcmFjdGlvbl9jb250cmFzdCkgJT4lCiAgYmFzZTo6bWVyZ2UoLiwgcm9idXN0X0FBVlMpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICByb2J1c3QgPSBmYWN0b3Iocm9idXN0LCBsZXZlbHMgPSBjKCJub3Qgcm9idXN0IiwgInJvYnVzdCIpKSkKCiNiYXllc3Rlc3RSOjpwX2RpcmVjdGlvbihkYXRhX21lQ29udHJhc3RzX0FBVlMpCgpwbG90X1JRMV9BQVZTIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX0FBVlMgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ID09ICJzZW5zb3JzIC0gYmVmb3JlIiksCiAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIHNlbnNvcnMgZWZmZWN0cyAobWVswrIpIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiKGIpIFJlc2VhcmNoIFF1ZXN0aW9uIDEiLAogICAgc3VidGl0bGUgPSAiU2Vuc29yIGVmZmVjdCAoV2l0aCBTZW5zb3JzIC0gQmVmb3JlIFNlbnNvcnMpXG5wZXIgZ3JvdXAgYW5kIHRoZSBlZmZlY3QgY29udHJhc3QgYmV0d2VlbiBncm91cHMuIiwKICAgIGZpbGwgPSAiUm9idXN0IGF0IDk1JSBIUEQgSW50ZXJ2YWwgJiBwZCIKICApICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIHRoZW1lX2NsZWFuKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RTdWJ0aXRsZSkKICApCgpwbG90X1JRMV9BQVZTCgpwbG90X1JRMl9BQVZTIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX0FBVlMgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ID09ICJhZnRlciAtIGJlZm9yZSIpLAogICAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIGFmdGVyLXNlbnNvclxuZWZmZWN0cyAobWVswrIpIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiKGMpIFJlc2VhcmNoIFF1ZXN0aW9uIDIiLAogICAgc3VidGl0bGUgPSAiQWZ0ZXItc2Vuc29yIGVmZmVjdCAoQWZ0ZXIgU2Vuc29ycyAtXG5CZWZvcmUgU2Vuc29ycykgcGVyIGdyb3VwIGFuZCB0aGVcbmVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlEyX0FBVlMKCiMgQ29tYmluZWQgcGxvdApwbG90X0FBVlMgPC0gIHBsb3RfZ3JhbmRNZWFuX0FBVlMgKyBwbG90X1JRMV9BQVZTICsgcGxvdF9SUTJfQUFWUyArCiAgcGF0Y2h3b3JrOjpwbG90X2xheW91dChuY29sID0gMywgaGVpZ2h0cyA9IGMoMSksIGd1aWRlcyA9ICJjb2xsZWN0IikgKwogIHBsb3RfYW5ub3RhdGlvbih0aXRsZSA9ICJBcnRpY3VsYXRvcnkgQWNvdXN0aWMgVm93ZWwgU3BhY2UiLCAjc3VidGl0bGUgPSAiUHJlZGljdGVkIGludGVsbGlnaWJpbGl0eSByYXRpbmdzIGFjcm9zcyBncm91cC9zZXZlcml0eSBhbmQgc3BlYWtpbmcgY29uZGl0aW9ucy4iLAogICAgICAgICAgICAgICAgICB0aGVtZSA9IHRoZW1lX2NsZWFuKCkpICYKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKcGxvdF9BQVZTCgpnZ3NhdmUoCiAgcGxvdCA9IHBsb3RfQUFWUywKICBmaWxlbmFtZSA9ICJGaWd1cmVzL0ZpZ19BQVZTLnBuZyIsCiAgaGVpZ2h0ID0gNiwKICB3aWR0aCA9IDEwLAogIHVuaXQgPSAiaW4iLAogIHNjYWxlID0gLjksCiAgYmcgPSAid2hpdGUiCikKCmBgYAojIDA0LiBNMQojIyAvcy8gLSBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQojIEdlbmVyYXRlIGV4cGVjdGVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHBvc3RlcmlvcgpkYXRhX3Bvc3Rlcmlvcl9NMXMgPC0gbW9kZWxfTTFzICU+JQogIHRpZHliYXllczo6ZXByZWRfZHJhd3MoCiAgICBuZXdkYXRhID0gdGlkeXI6OmV4cGFuZF9ncmlkKAogICAgICBncm91cCA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgdGltZV9wb2ludCA9IGMoImJlZm9yZSIsICJzZW5zb3JzIiwgImFmdGVyIiksCiAgICAgIHNleCA9IGMoIk1hbGUiLCAiRmVtYWxlIiksCiAgICAgIGFnZSA9IG1lYW4obW9kZWxfTTFzJGRhdGEkYWdlKSwKICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfTTFzJGRhdGEkYXJ0aWNfcmF0ZSksCiAgICApLAogICAgcmVfZm9ybXVsYSA9IE5BCiAgKSAlPiUKICBncm91cF9ieSguZHJhdywgZ3JvdXAsIHRpbWVfcG9pbnQpICU+JQogIHN1bW1hcml6ZSguZXByZWQgPSBtZWFuKC5lcHJlZCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICBncm91cCA9IGZhY3RvcigKICAgICAgZ3JvdXAsCiAgICAgIGxldmVscyA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJQd1BEIikKICAgICksCiAgICAjZ3JvdXBpbmcgPSBwYXN0ZShzZXgsIGdyb3VwLCBzZXAgPSAiIC0gIiksCiAgICAjZ3JvdXBpbmcgPSBmYWN0b3IoZ3JvdXBpbmcsCiAgICAjICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hbGUgLSBQd1BEIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBQd1BEIikpLAogICAgdGltZV9wb2ludCA9IGZhY3RvcigKICAgICAgdGltZV9wb2ludCwKICAgICAgbGV2ZWxzID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgbGFiZWxzID0gYygiQmVmb3JlXG5TZW5zb3JzIiwgIldpdGhcblNlbnNvcnMiLCAiQWZ0ZXJcblNlbnNvcnMiKQogICAgKQogICkKCmBgYAoKIyMgL3MvIC0gTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpyb2J1c3RfTTFzIDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX00xcy5SRFMiKSRwYWlyd2lzZSAlPiUKICBkcGx5cjo6c2VsZWN0KGNvbnRyYXN0LCBncm91cCwgcm9idXN0KQoKZGF0YV9tZUNvbnRyYXN0c19NMXMgPC0gbW9kZWxfTTFzICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50IHwgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICBlcHJlZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICByZV9mb3JtdWxhID0gTkEsKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfTTFzICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50ICogZ3JvdXAsIGVwcmVkID0gVFJVRSwgcmVfZm9ybXVsYSA9IE5BKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChpbnRlcmFjdGlvbiA9ICJyZXZwYWlyd2lzZSIpICU+JQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lCiAgZHBseXI6OnJlbmFtZShjb250cmFzdCA9IHRpbWVfcG9pbnRfcmV2cGFpcndpc2UsCiAgICAgICAgICAgICAgICBncm91cCA9IGdyb3VwX3JldnBhaXJ3aXNlKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKZGF0YV9tZUNvbnRyYXN0c19NMXMgPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19NMXMsIGludGVyYWN0aW9uX2NvbnRyYXN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgZ3JvdXAgPT0gIlBEIiB+ICJQd1BEIiwKICAgIGdyb3VwID09ICJDb250cm9sIiB+ICJDb250cm9sIiwKICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICApKSAlPiUKICBiYXNlOjptZXJnZSguLCByb2J1c3RfTTFzKSAlPiUKICBkcGx5cjo6bXV0YXRlKHJvYnVzdCA9IGZhY3Rvcihyb2J1c3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygibm90IHJvYnVzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicm9idXN0IikpKQoKI2JheWVzdGVzdFI6OnBfZGlyZWN0aW9uKGRhdGFfbWVDb250cmFzdHNfTTFzKQoKYGBgCgojIyAvc2gvIC0gRXhwZWN0ZWQgUG9zdGVyaW9ycwpgYGB7cn0KIyBHZW5lcmF0ZSBleHBlY3RlZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKZGF0YV9wb3N0ZXJpb3JfTTFzaCA8LSBtb2RlbF9NMXNoICU+JQogIHRpZHliYXllczo6ZXByZWRfZHJhd3MoCiAgICBuZXdkYXRhID0gdGlkeXI6OmV4cGFuZF9ncmlkKAogICAgICBncm91cCA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgdGltZV9wb2ludCA9IGMoImJlZm9yZSIsICJzZW5zb3JzIiwgImFmdGVyIiksCiAgICAgIHNleCA9IGMoIk1hbGUiLCAiRmVtYWxlIiksCiAgICAgIGFnZSA9IG1lYW4obW9kZWxfTTFzaCRkYXRhJGFnZSksCiAgICAgIGFydGljX3JhdGUgPSBtZWFuKG1vZGVsX00xc2gkZGF0YSRhcnRpY19yYXRlKSwKICAgICksCiAgICByZV9mb3JtdWxhID0gTkEKICApICU+JQogIGdyb3VwX2J5KC5kcmF3LCBncm91cCwgdGltZV9wb2ludCkgJT4lCiAgc3VtbWFyaXplKC5lcHJlZCA9IG1lYW4oLmVwcmVkKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIGdyb3VwID0gZmFjdG9yKAogICAgICBncm91cCwKICAgICAgbGV2ZWxzID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwgIlB3UEQiKQogICAgKSwKICAgICNncm91cGluZyA9IHBhc3RlKHNleCwgZ3JvdXAsIHNlcCA9ICIgLSAiKSwKICAgICNncm91cGluZyA9IGZhY3Rvcihncm91cGluZywKICAgICMgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFsZSAtIFB3UEQiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIFB3UEQiKSksCiAgICB0aW1lX3BvaW50ID0gZmFjdG9yKAogICAgICB0aW1lX3BvaW50LAogICAgICBsZXZlbHMgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBsYWJlbHMgPSBjKCJCZWZvcmVcblNlbnNvcnMiLCAiV2l0aFxuU2Vuc29ycyIsICJBZnRlclxuU2Vuc29ycyIpCiAgICApCiAgKQoKYGBgCgojIyAvc2gvIC0gTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpyb2J1c3RfTTFzaCA8LSByaW86OmltcG9ydCgid29ya2luZ0RhdGEvZGF0YV9NMXNoLlJEUyIpJHBhaXJ3aXNlICU+JQogIGRwbHlyOjpzZWxlY3QoY29udHJhc3QsIGdyb3VwLCByb2J1c3QpCgpkYXRhX21lQ29udHJhc3RzX00xc2ggPC0gbW9kZWxfTTFzaCAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCB8IGdyb3VwLAogICAgICAgICAgICAgICAgICAgZXByZWQgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgcmVfZm9ybXVsYSA9IE5BLCkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QobWV0aG9kID0gInJldnBhaXJ3aXNlIikgJT4lCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKIyBDb21wdXRlIHRoZSBpbnRlcmFjdGlvbiBjb250cmFzdCAoZGlmZmVyZW5jZSBpbiBjb250cmFzdHMgYmV0d2VlbiBncm91cHMpCmludGVyYWN0aW9uX2NvbnRyYXN0IDwtIG1vZGVsX00xc2ggJT4lCiAgZW1tZWFuczo6ZW1tZWFucyh+IHRpbWVfcG9pbnQgKiBncm91cCwgZXByZWQgPSBUUlVFLCByZV9mb3JtdWxhID0gTkEpICU+JQogIGVtbWVhbnM6OmNvbnRyYXN0KGludGVyYWN0aW9uID0gInJldnBhaXJ3aXNlIikgJT4lCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUKICBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0ID0gdGltZV9wb2ludF9yZXZwYWlyd2lzZSwKICAgICAgICAgICAgICAgIGdyb3VwID0gZ3JvdXBfcmV2cGFpcndpc2UpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgpkYXRhX21lQ29udHJhc3RzX00xc2ggPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19NMXNoLCBpbnRlcmFjdGlvbl9jb250cmFzdCkgJT4lCiAgZHBseXI6Om11dGF0ZShncm91cCA9IGNhc2Vfd2hlbigKICAgIGdyb3VwID09ICJQRCIgfiAiUHdQRCIsCiAgICBncm91cCA9PSAiQ29udHJvbCIgfiAiQ29udHJvbCIsCiAgICBncm91cCA9PSAiUEQgLSBDb250cm9sIiB+ICJQd1BEIC1cbkNvbnRyb2wiCiAgKSkgJT4lCiAgYmFzZTo6bWVyZ2UoLiwgcm9idXN0X00xc2gpICU+JQogIGRwbHlyOjptdXRhdGUocm9idXN0ID0gZmFjdG9yKHJvYnVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJub3Qgcm9idXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyb2J1c3QiKSkpCgojYmF5ZXN0ZXN0Ujo6cF9kaXJlY3Rpb24oZGF0YV9tZUNvbnRyYXN0c19NMXNoKQoKYGBgCiMjIENvbWJpbmVkCiMjIyBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQojIEdlbmVyYXRlIGV4cGVjdGVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHBvc3RlcmlvcgpkYXRhX3Bvc3Rlcmlvcl9NMSA8LSByYmluZChkYXRhX3Bvc3Rlcmlvcl9NMXMgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShzb3VuZCA9ICIvcy8iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YV9wb3N0ZXJpb3JfTTFzaCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHNvdW5kID0gIi/Kgy8iKSkKCnBsb3RfZ3JhbmRNZWFuX00xIDwtIGdncGxvdChkYXRhX3Bvc3Rlcmlvcl9NMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSAuZXByZWQsIHkgPSB0aW1lX3BvaW50LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IGdyb3VwKSkgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgZ2dva2FiZWl0bzo6c2NhbGVfZmlsbF9va2FiZV9pdG8ob3JkZXIgPSBjKDIsIDEpKSArCiAgbGFicyh4ID0gIlByZWRpY3RlZCBNMSAoa0h6KSIsIHkgPSBOVUxMLAogICAgICAgZmlsbCA9ICJHcm91cCIsCiAgICAgICB0aXRsZSA9ICIoYSkgUG9zdGVyaW9yIFByZWRpY3Rpb25zIiwKICAgICAgIHN1YnRpdGxlID0gIlByZWRpY3RlZCBNMSBhZnRlciBjb250cm9sbGluZyBmb3JcbnNwZWFrZXIgYWdlLCBzZXgsIGFuZCBhcnRpY3VsYXRpb24gcmF0ZS4iKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICBmYWNldF93cmFwKH5zb3VuZCwgbmNvbCA9IDEpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKSkgICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpCmBgYAoKIyMjIE1FOiBUaW1lcG9pbnQgeCBHcm91cApgYGB7cn0KZGF0YV9tZUNvbnRyYXN0c19NMSA8LSByYmluZChkYXRhX21lQ29udHJhc3RzX00xcyAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHNvdW5kID0gIi9zLyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhX21lQ29udHJhc3RzX00xc2ggJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShzb3VuZCA9ICIvyoMvIikpCgojYmF5ZXN0ZXN0Ujo6cF9kaXJlY3Rpb24oZGF0YV9tZUNvbnRyYXN0c19NMSkKCnBsb3RfUlExX00xIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX00xICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAic2Vuc29ycyAtIGJlZm9yZSIpLAogIGFlcyh4ID0gLnZhbHVlLCB5ID0gZ3JvdXAsIGZpbGwgPSByb2J1c3QpCikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGFscGhhID0gLjMpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFM0I1Q0YiLCAiI0NDNzlBNyIpLAogICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpICsKICBsYWJzKAogICAgeCA9ICJBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdCBvZiBzZW5zb3JzIGVmZmVjdHMgKGtIeikiLAogICAgeSA9IE5VTEwsCiAgICB0aXRsZSA9ICIoYikgUmVzZWFyY2ggUXVlc3Rpb24gMSIsCiAgICBzdWJ0aXRsZSA9ICJTZW5zb3IgZWZmZWN0IChXaXRoIFNlbnNvcnMgLSBCZWZvcmUgU2Vuc29ycylcbnBlciBncm91cCBhbmQgdGhlIGVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgZmFjZXRfd3JhcCh+c291bmQsIG5jb2wgPSAxKSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlExX00xCgpwbG90X1JRMl9NMSA8LSBnZ3Bsb3QoCiAgZGF0YV9tZUNvbnRyYXN0c19NMSAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgPT0gImFmdGVyIC0gYmVmb3JlIiksCiAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIGFmdGVyLXNlbnNvclxuZWZmZWN0cyAoa0h6KSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihjKSBSZXNlYXJjaCBRdWVzdGlvbiAyIiwKICAgIHN1YnRpdGxlID0gIkFmdGVyLXNlbnNvciBlZmZlY3QgKEFmdGVyIFNlbnNvcnMgLVxuQmVmb3JlIFNlbnNvcnMpIHBlciBncm91cCBhbmQgdGhlXG5lZmZlY3QgY29udHJhc3QgYmV0d2VlbiBncm91cHMuIiwKICAgIGZpbGwgPSAiUm9idXN0IGF0IDk1JSBIUEQgSW50ZXJ2YWwgJiBwZCIKICApICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIGZhY2V0X3dyYXAofnNvdW5kLCBuY29sID0gMSkgKwogIHRoZW1lX2NsZWFuKCkgKwogIHRoZW1lKAogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RTdWJ0aXRsZSkKICApCgpwbG90X1JRMl9NMQoKIyBDb21iaW5lZCBwbG90CnBsb3RfTTEgPC0gIHBsb3RfZ3JhbmRNZWFuX00xICsgcGxvdF9SUTFfTTEgKyBwbG90X1JRMl9NMSArCiAgcGF0Y2h3b3JrOjpwbG90X2xheW91dChuY29sID0gMywgaGVpZ2h0cyA9IGMoMSksIGd1aWRlcyA9ICJjb2xsZWN0IikgKwogIHBsb3RfYW5ub3RhdGlvbih0aXRsZSA9ICJTcGVjdHJhbCBDZW50ZXIgb2YgR3Jhdml0eSAoTTEpIiwgI3N1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5ncyBhY3Jvc3MgZ3JvdXAvc2V2ZXJpdHkgYW5kIHNwZWFraW5nIGNvbmRpdGlvbnMuIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCnBsb3RfTTEKCmdnc2F2ZSgKICBwbG90ID0gcGxvdF9NMSwKICBmaWxlbmFtZSA9ICJGaWd1cmVzL0ZpZ19NMS5wbmciLAogIGhlaWdodCA9IDcsCiAgd2lkdGggPSAxMCwKICB1bml0ID0gImluIiwKICBzY2FsZSA9IC45LAogIGJnID0gIndoaXRlIgopCgpgYGAKCiMgMDUuIE0yCiMjIC9zLyAtIEV4cGVjdGVkIFBvc3RlcmlvcnMKYGBge3J9CiMgR2VuZXJhdGUgZXhwZWN0ZWQgcHJlZGljdGlvbnMgZnJvbSB0aGUgcG9zdGVyaW9yCmRhdGFfcG9zdGVyaW9yX00ycyA8LSBtb2RlbF9NMnMgJT4lCiAgdGlkeWJheWVzOjplcHJlZF9kcmF3cygKICAgIG5ld2RhdGEgPSB0aWR5cjo6ZXhwYW5kX2dyaWQoCiAgICAgIGdyb3VwID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICB0aW1lX3BvaW50ID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgc2V4ID0gYygiTWFsZSIsICJGZW1hbGUiKSwKICAgICAgYWdlID0gbWVhbihtb2RlbF9NMnMkZGF0YSRhZ2UpLAogICAgICBhcnRpY19yYXRlID0gbWVhbihtb2RlbF9NMnMkZGF0YSRhcnRpY19yYXRlKSwKICAgICksCiAgICByZV9mb3JtdWxhID0gTkEKICApICU+JQogIGdyb3VwX2J5KC5kcmF3LCBncm91cCwgdGltZV9wb2ludCkgJT4lCiAgc3VtbWFyaXplKC5lcHJlZCA9IG1lYW4oLmVwcmVkKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIGdyb3VwID0gZmFjdG9yKAogICAgICBncm91cCwKICAgICAgbGV2ZWxzID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwgIlB3UEQiKQogICAgKSwKICAgICNncm91cGluZyA9IHBhc3RlKHNleCwgZ3JvdXAsIHNlcCA9ICIgLSAiKSwKICAgICNncm91cGluZyA9IGZhY3Rvcihncm91cGluZywKICAgICMgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFsZSAtIFB3UEQiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSAtIFB3UEQiKSksCiAgICB0aW1lX3BvaW50ID0gZmFjdG9yKAogICAgICB0aW1lX3BvaW50LAogICAgICBsZXZlbHMgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBsYWJlbHMgPSBjKCJCZWZvcmVcblNlbnNvcnMiLCAiV2l0aFxuU2Vuc29ycyIsICJBZnRlclxuU2Vuc29ycyIpCiAgICApCiAgKQoKYGBgCgojIyAvcy8gLSBNRTogVGltZXBvaW50IHggR3JvdXAKYGBge3J9CnJvYnVzdF9NMnMgPC0gcmlvOjppbXBvcnQoIndvcmtpbmdEYXRhL2RhdGFfTTJzLlJEUyIpJHBhaXJ3aXNlICU+JQogIGRwbHlyOjpzZWxlY3QoY29udHJhc3QsIGdyb3VwLCByb2J1c3QpCgpkYXRhX21lQ29udHJhc3RzX00ycyA8LSBtb2RlbF9NMnMgJT4lCiAgZW1tZWFuczo6ZW1tZWFucyh+IHRpbWVfcG9pbnQgfCBncm91cCwKICAgICAgICAgICAgICAgICAgIGVwcmVkID0gVFJVRSwKICAgICAgICAgICAgICAgICAgIHJlX2Zvcm11bGEgPSBOQSwpICU+JQogIGVtbWVhbnM6OmNvbnRyYXN0KG1ldGhvZCA9ICJyZXZwYWlyd2lzZSIpICU+JQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lCiAgZHBseXI6OmZpbHRlcihjb250cmFzdCAhPSAiYWZ0ZXIgLSBzZW5zb3JzIikKCiMgQ29tcHV0ZSB0aGUgaW50ZXJhY3Rpb24gY29udHJhc3QgKGRpZmZlcmVuY2UgaW4gY29udHJhc3RzIGJldHdlZW4gZ3JvdXBzKQppbnRlcmFjdGlvbl9jb250cmFzdCA8LSBtb2RlbF9NMnMgJT4lCiAgZW1tZWFuczo6ZW1tZWFucyh+IHRpbWVfcG9pbnQgKiBncm91cCwgZXByZWQgPSBUUlVFLCByZV9mb3JtdWxhID0gTkEpICU+JQogIGVtbWVhbnM6OmNvbnRyYXN0KGludGVyYWN0aW9uID0gInJldnBhaXJ3aXNlIikgJT4lCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUKICBkcGx5cjo6cmVuYW1lKGNvbnRyYXN0ID0gdGltZV9wb2ludF9yZXZwYWlyd2lzZSwKICAgICAgICAgICAgICAgIGdyb3VwID0gZ3JvdXBfcmV2cGFpcndpc2UpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgpkYXRhX21lQ29udHJhc3RzX00ycyA8LSBiYXNlOjpyYmluZChkYXRhX21lQ29udHJhc3RzX00ycywgaW50ZXJhY3Rpb25fY29udHJhc3QpICU+JQogIGRwbHlyOjptdXRhdGUoZ3JvdXAgPSBjYXNlX3doZW4oCiAgICBncm91cCA9PSAiUEQiIH4gIlB3UEQiLAogICAgZ3JvdXAgPT0gIkNvbnRyb2wiIH4gIkNvbnRyb2wiLAogICAgZ3JvdXAgPT0gIlBEIC0gQ29udHJvbCIgfiAiUHdQRCAtXG5Db250cm9sIgogICkpICU+JQogIGJhc2U6Om1lcmdlKC4sIHJvYnVzdF9NMnMpICU+JQogIGRwbHlyOjptdXRhdGUocm9idXN0ID0gZmFjdG9yKHJvYnVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJub3Qgcm9idXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyb2J1c3QiKSkpCgojYmF5ZXN0ZXN0Ujo6cF9kaXJlY3Rpb24oZGF0YV9tZUNvbnRyYXN0c19NMnMpCgpgYGAKCiMjIC9zaC8gLSBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQojIEdlbmVyYXRlIGV4cGVjdGVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHBvc3RlcmlvcgpkYXRhX3Bvc3Rlcmlvcl9NMnNoIDwtIG1vZGVsX00yc2ggJT4lCiAgdGlkeWJheWVzOjplcHJlZF9kcmF3cygKICAgIG5ld2RhdGEgPSB0aWR5cjo6ZXhwYW5kX2dyaWQoCiAgICAgIGdyb3VwID0gYygiQ29udHJvbCIsICJQRCIpLAogICAgICB0aW1lX3BvaW50ID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgc2V4ID0gYygiTWFsZSIsICJGZW1hbGUiKSwKICAgICAgYWdlID0gbWVhbihtb2RlbF9NMnNoJGRhdGEkYWdlKSwKICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfTTJzaCRkYXRhJGFydGljX3JhdGUpLAogICAgKSwKICAgIHJlX2Zvcm11bGEgPSBOQQogICkgJT4lCiAgZ3JvdXBfYnkoLmRyYXcsIGdyb3VwLCB0aW1lX3BvaW50KSAlPiUKICBzdW1tYXJpemUoLmVwcmVkID0gbWVhbiguZXByZWQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBkcGx5cjo6bXV0YXRlKAogICAgZ3JvdXAgPSBmYWN0b3IoCiAgICAgIGdyb3VwLAogICAgICBsZXZlbHMgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIGxhYmVscyA9IGMoIkNvbnRyb2wiLCAiUHdQRCIpCiAgICApLAogICAgI2dyb3VwaW5nID0gcGFzdGUoc2V4LCBncm91cCwgc2VwID0gIiAtICIpLAogICAgI2dyb3VwaW5nID0gZmFjdG9yKGdyb3VwaW5nLAogICAgIyAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWxlIC0gUHdQRCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gQ29udHJvbCIsCiAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gUHdQRCIpKSwKICAgIHRpbWVfcG9pbnQgPSBmYWN0b3IoCiAgICAgIHRpbWVfcG9pbnQsCiAgICAgIGxldmVscyA9IGMoImJlZm9yZSIsICJzZW5zb3JzIiwgImFmdGVyIiksCiAgICAgIGxhYmVscyA9IGMoIkJlZm9yZVxuU2Vuc29ycyIsICJXaXRoXG5TZW5zb3JzIiwgIkFmdGVyXG5TZW5zb3JzIikKICAgICkKICApCgpgYGAKCiMjIC9zaC8gLSBNRTogVGltZXBvaW50IHggR3JvdXAKYGBge3J9CnJvYnVzdF9NMnNoIDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX00yc2guUkRTIikkcGFpcndpc2UgJT4lCiAgZHBseXI6OnNlbGVjdChjb250cmFzdCwgZ3JvdXAsIHJvYnVzdCkKCmRhdGFfbWVDb250cmFzdHNfTTJzaCA8LSBtb2RlbF9NMnNoICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50IHwgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICBlcHJlZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICByZV9mb3JtdWxhID0gTkEsKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfTTJzaCAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCAqIGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QoaW50ZXJhY3Rpb24gPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjpyZW5hbWUoY29udHJhc3QgPSB0aW1lX3BvaW50X3JldnBhaXJ3aXNlLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBncm91cF9yZXZwYWlyd2lzZSkgJT4lCiAgZHBseXI6OmZpbHRlcihjb250cmFzdCAhPSAiYWZ0ZXIgLSBzZW5zb3JzIikKCmRhdGFfbWVDb250cmFzdHNfTTJzaCA8LSBiYXNlOjpyYmluZChkYXRhX21lQ29udHJhc3RzX00yc2gsIGludGVyYWN0aW9uX2NvbnRyYXN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgZ3JvdXAgPT0gIlBEIiB+ICJQd1BEIiwKICAgIGdyb3VwID09ICJDb250cm9sIiB+ICJDb250cm9sIiwKICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICApKSAlPiUKICBiYXNlOjptZXJnZSguLCByb2J1c3RfTTJzaCkgJT4lCiAgZHBseXI6Om11dGF0ZShyb2J1c3QgPSBmYWN0b3Iocm9idXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIm5vdCByb2J1c3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJvYnVzdCIpKSkKCiNiYXllc3Rlc3RSOjpwX2RpcmVjdGlvbihkYXRhX21lQ29udHJhc3RzX00yc2gpCgpgYGAKIyMgQ29tYmluZWQKIyMjIEV4cGVjdGVkIFBvc3RlcmlvcnMKYGBge3J9CiMgR2VuZXJhdGUgZXhwZWN0ZWQgcHJlZGljdGlvbnMgZnJvbSB0aGUgcG9zdGVyaW9yCmRhdGFfcG9zdGVyaW9yX00yIDwtIHJiaW5kKGRhdGFfcG9zdGVyaW9yX00ycyAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHNvdW5kID0gIi9zLyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhX3Bvc3Rlcmlvcl9NMnNoICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUoc291bmQgPSAiL8qDLyIpKQoKcGxvdF9ncmFuZE1lYW5fTTIgPC0gZ2dwbG90KGRhdGFfcG9zdGVyaW9yX00yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IC5lcHJlZCwgeSA9IHRpbWVfcG9pbnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gZ3JvdXApKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBnZ29rYWJlaXRvOjpzY2FsZV9maWxsX29rYWJlX2l0byhvcmRlciA9IGMoMiwgMSkpICsKICBsYWJzKHggPSAiUHJlZGljdGVkIE0yIChrSHopIiwgeSA9IE5VTEwsCiAgICAgICBmaWxsID0gIkdyb3VwIiwKICAgICAgIHRpdGxlID0gIihhKSBQb3N0ZXJpb3IgUHJlZGljdGlvbnMiLAogICAgICAgc3VidGl0bGUgPSAiUHJlZGljdGVkIE0yIGFmdGVyIGNvbnRyb2xsaW5nIGZvclxuc3BlYWtlciBhZ2UsIHNleCwgYW5kIGFydGljdWxhdGlvbiByYXRlLiIpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIHRoZW1lX2NsZWFuKCkgKwogIGZhY2V0X3dyYXAofnNvdW5kLCBuY29sID0gMSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFRpdGxlKSwKICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpKSAgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkKYGBgCgojIyMgTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpkYXRhX21lQ29udHJhc3RzX00yIDwtIHJiaW5kKGRhdGFfbWVDb250cmFzdHNfTTJzICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUoc291bmQgPSAiL3MvIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFfbWVDb250cmFzdHNfTTJzaCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHNvdW5kID0gIi/Kgy8iKSkKCiNiYXllc3Rlc3RSOjpwX2RpcmVjdGlvbihkYXRhX21lQ29udHJhc3RzX00yKQoKcGxvdF9SUTFfTTIgPC0gZ2dwbG90KAogIGRhdGFfbWVDb250cmFzdHNfTTIgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ID09ICJzZW5zb3JzIC0gYmVmb3JlIiksCiAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIHNlbnNvcnMgZWZmZWN0cyAoa0h6KSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihiKSBSZXNlYXJjaCBRdWVzdGlvbiAxIiwKICAgIHN1YnRpdGxlID0gIlNlbnNvciBlZmZlY3QgKFdpdGggU2Vuc29ycyAtIEJlZm9yZSBTZW5zb3JzKVxucGVyIGdyb3VwIGFuZCB0aGUgZWZmZWN0IGNvbnRyYXN0IGJldHdlZW4gZ3JvdXBzLiIsCiAgICBmaWxsID0gIlJvYnVzdCBhdCA5NSUgSFBEIEludGVydmFsICYgcGQiCiAgKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICBmYWNldF93cmFwKH5zb3VuZCwgbmNvbCA9IDEpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpCiAgKQoKcGxvdF9SUTFfTTIKCnBsb3RfUlEyX00yIDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX00yICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAiYWZ0ZXIgLSBiZWZvcmUiKSwKICBhZXMoeCA9IC52YWx1ZSwgeSA9IGdyb3VwLCBmaWxsID0gcm9idXN0KQopICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBhbHBoYSA9IC4zKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRTNCNUNGIiwgIiNDQzc5QTciKSwKICAgICAgICAgICAgICAgICAgICAgZHJvcCA9IEZBTFNFKSArCiAgbGFicygKICAgIHggPSAiQXZlcmFnZSBtYXJnaW5hbCBlZmZlY3Qgb2YgYWZ0ZXItc2Vuc29yXG5lZmZlY3RzIChrSHopIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiKGMpIFJlc2VhcmNoIFF1ZXN0aW9uIDIiLAogICAgc3VidGl0bGUgPSAiQWZ0ZXItc2Vuc29yIGVmZmVjdCAoQWZ0ZXIgU2Vuc29ycyAtXG5CZWZvcmUgU2Vuc29ycykgcGVyIGdyb3VwIGFuZCB0aGVcbmVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgZmFjZXRfd3JhcCh+c291bmQsIG5jb2wgPSAxKSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlEyX00yCgojIENvbWJpbmVkIHBsb3QKcGxvdF9NMiA8LSAgcGxvdF9ncmFuZE1lYW5fTTIgKyBwbG90X1JRMV9NMiArIHBsb3RfUlEyX00yICsKICBwYXRjaHdvcms6OnBsb3RfbGF5b3V0KG5jb2wgPSAzLCBoZWlnaHRzID0gYygxKSwgZ3VpZGVzID0gImNvbGxlY3QiKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gIlNwZWN0cmFsIFN0YW5kYXJkIERldmlhdGlvbiAoTTIpIiwgI3N1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5ncyBhY3Jvc3MgZ3JvdXAvc2V2ZXJpdHkgYW5kIHNwZWFraW5nIGNvbmRpdGlvbnMuIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCnBsb3RfTTIKCmdnc2F2ZSgKICBwbG90ID0gcGxvdF9NMiwKICBmaWxlbmFtZSA9ICJGaWd1cmVzL0ZpZ19NMi5wbmciLAogIGhlaWdodCA9IDcsCiAgd2lkdGggPSAxMCwKICB1bml0ID0gImluIiwKICBzY2FsZSA9IC45LAogIGJnID0gIndoaXRlIgopCgpgYGAKCiMgMDYuIEludGVsbGlnaWJpbGl0eQojIyBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQplcHNpbG9uIDwtIDFlLTUKIyBHZW5lcmF0ZSBleHBlY3RlZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKZGF0YV9wb3N0ZXJpb3JfSW50IDwtIG1vZGVsX0ludCAlPiUKICB0aWR5YmF5ZXM6OmVwcmVkX2RyYXdzKAogICAgbmV3ZGF0YSA9IHRpZHlyOjpleHBhbmRfZ3JpZCgKICAgICAgZ3JvdXAgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIHRpbWVfcG9pbnQgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBzZXggPSBjKCJNYWxlIiwgIkZlbWFsZSIpLAogICAgICBhZ2UgPSBtZWFuKG1vZGVsX0ludCRkYXRhJGFnZSksICMgNjYuOTEgeW8KICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfSW50JGRhdGEkYXJ0aWNfcmF0ZSksICMgNC44NSBzeWwvcwogICAgICB0cmlhbF9udW1iZXIgPSBtZWFuKG1vZGVsX0ludCRkYXRhJHRyaWFsX251bWJlcikgIyB0cmlhbCA5CiAgICApLAogICAgcmVfZm9ybXVsYSA9IE5BCiAgKSAlPiUKICBncm91cF9ieSguZHJhdywgZ3JvdXAsIHRpbWVfcG9pbnQpICU+JQogIHN1bW1hcml6ZSguZXByZWQgPSBtZWFuKC5lcHJlZCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICBncm91cCA9IGZhY3RvcigKICAgICAgZ3JvdXAsCiAgICAgIGxldmVscyA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJQd1BEIikKICAgICksCiAgICAjZ3JvdXBpbmcgPSBwYXN0ZShzZXgsIGdyb3VwLCBzZXAgPSAiIC0gIiksCiAgICAjZ3JvdXBpbmcgPSBmYWN0b3IoZ3JvdXBpbmcsCiAgICAjICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hbGUgLSBQd1BEIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBQd1BEIikpLAogICAgdGltZV9wb2ludCA9IGZhY3RvcigKICAgICAgdGltZV9wb2ludCwKICAgICAgbGV2ZWxzID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgbGFiZWxzID0gYygiQmVmb3JlXG5TZW5zb3JzIiwgIldpdGhcblNlbnNvcnMiLCAiQWZ0ZXJcblNlbnNvcnMiKQogICAgKSwKICAgIC5lcHJlZCA9ICguZXByZWQgLSBlcHNpbG9uKSAvICgxIC0gMiAqIGVwc2lsb24pLAogICAgIyBTdGVwIDEgJiAyOiBSZXZlcnNlIHRoZSBvZmZzZXQgYW5kIHNjYWxpbmcKICAgIC5lcHJlZCA9IC5lcHJlZCAqIG5yb3coLikgLyAoKG5yb3coLikgLSAxKSArIC41KSwKICAgIC5lcHJlZCA9IC5lcHJlZCAqIDEwMCAjIHRvIHR1cm4gaXQgYmFjayB0byBhIHNjYWxlIG9mIDAgLSAxMDAKICApCgpwbG90X2dyYW5kTWVhbl9JbnQgPC0gZ2dwbG90KGRhdGFfcG9zdGVyaW9yX0ludCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSAuZXByZWQsIHkgPSB0aW1lX3BvaW50LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IGdyb3VwKSkgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgZ2dva2FiZWl0bzo6c2NhbGVfZmlsbF9va2FiZV9pdG8ob3JkZXIgPSBjKDIsIDEpKSArCiAgbGFicyh4ID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5nICglKSIsIHkgPSBOVUxMLAogICAgICAgZmlsbCA9ICJHcm91cCIsCiAgICAgICB0aXRsZSA9ICIoYSkgUG9zdGVyaW9yIFByZWRpY3Rpb25zIiwKICAgICAgIHN1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5nIGFmdGVyIGNvbnRyb2xsaW5nXG5mb3Igc3BlYWtlciBhZ2UsIHNleCwgYXJ0aWN1bGF0aW9uIHJhdGUsXG5hbmQgdHJpYWwgbnVtYmVyLiIpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYyg3MiwxMDApKSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RTdWJ0aXRsZSksCiAgICAgICAgI3BhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJncmV5IiwgZmlsbCA9IE5BKQogICAgICAgICkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkKYGBgCgojIyBNRTogVGltZXBvaW50IHggR3JvdXAKYGBge3J9CnJvYnVzdF9JbnQgPC0gcmlvOjppbXBvcnQoIndvcmtpbmdEYXRhL2RhdGFfSW50LlJEUyIpJHBhaXJ3aXNlICU+JQogIGRwbHlyOjpzZWxlY3QoY29udHJhc3QsIGdyb3VwLCByb2J1c3QpCgplcHNpbG9uIDwtIDFlLTUKZGF0YV9tZUNvbnRyYXN0c19JbnQgPC0gbW9kZWxfSW50ICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50IHwgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICBlcHJlZCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICByZV9mb3JtdWxhID0gTkEsKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChtZXRob2QgPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICAudmFsdWUgPSAoLnZhbHVlIC0gZXBzaWxvbikgLyAoMSAtIDIgKiBlcHNpbG9uKSwKICAgICMgU3RlcCAxICYgMjogUmV2ZXJzZSB0aGUgb2Zmc2V0IGFuZCBzY2FsaW5nCiAgICAudmFsdWUgPSAudmFsdWUgKiBucm93KC4pIC8gKChucm93KC4pIC0gMSkgKyAuNSksCiAgICAudmFsdWUgPSAudmFsdWUgKiAxMDAKICApICU+JQogIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgIT0gImFmdGVyIC0gc2Vuc29ycyIpCgojIENvbXB1dGUgdGhlIGludGVyYWN0aW9uIGNvbnRyYXN0IChkaWZmZXJlbmNlIGluIGNvbnRyYXN0cyBiZXR3ZWVuIGdyb3VwcykKaW50ZXJhY3Rpb25fY29udHJhc3QgPC0gbW9kZWxfSW50ICU+JQogIGVtbWVhbnM6OmVtbWVhbnMofiB0aW1lX3BvaW50ICogZ3JvdXAsIGVwcmVkID0gVFJVRSwgcmVfZm9ybXVsYSA9IE5BKSAlPiUKICBlbW1lYW5zOjpjb250cmFzdChpbnRlcmFjdGlvbiA9ICJyZXZwYWlyd2lzZSIpICU+JQogIGdhdGhlcl9lbW1lYW5zX2RyYXdzKCkgJT4lCiAgZHBseXI6Om11dGF0ZSgKICAgIC52YWx1ZSA9ICgudmFsdWUgLSBlcHNpbG9uKSAvICgxIC0gMiAqIGVwc2lsb24pLAogICAgIyBTdGVwIDEgJiAyOiBSZXZlcnNlIHRoZSBvZmZzZXQgYW5kIHNjYWxpbmcKICAgIC52YWx1ZSA9IC52YWx1ZSAqIG5yb3coLikgLyAoKG5yb3coLikgLSAxKSArIC41KSwKICAgIC52YWx1ZSA9IC52YWx1ZSAqIDEwMAogICkgJT4lCiAgZHBseXI6OnJlbmFtZShjb250cmFzdCA9IHRpbWVfcG9pbnRfcmV2cGFpcndpc2UsCiAgICAgICAgICAgICAgICBncm91cCA9IGdyb3VwX3JldnBhaXJ3aXNlKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKZGF0YV9tZUNvbnRyYXN0c19JbnQgPC0gYmFzZTo6cmJpbmQoZGF0YV9tZUNvbnRyYXN0c19JbnQsIGludGVyYWN0aW9uX2NvbnRyYXN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGdyb3VwID0gY2FzZV93aGVuKAogICAgZ3JvdXAgPT0gIlBEIiB+ICJQd1BEIiwKICAgIGdyb3VwID09ICJDb250cm9sIiB+ICJDb250cm9sIiwKICAgIGdyb3VwID09ICJQRCAtIENvbnRyb2wiIH4gIlB3UEQgLVxuQ29udHJvbCIKICApKSAlPiUKICBiYXNlOjptZXJnZSguLCByb2J1c3RfSW50KSAlPiUKICBkcGx5cjo6bXV0YXRlKHJvYnVzdCA9IGZhY3Rvcihyb2J1c3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygibm90IHJvYnVzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicm9idXN0IikpKQoKcGxvdF9SUTFfSW50IDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX0ludCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgPT0gInNlbnNvcnMgLSBiZWZvcmUiKSwKICBhZXMoeCA9IC52YWx1ZSwgeSA9IGdyb3VwLCBmaWxsID0gcm9idXN0KQopICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBhbHBoYSA9IC4zKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRTNCNUNGIiwgIiNDQzc5QTciKSwKICAgICAgICAgICAgICAgICAgICAgZHJvcCA9IEZBTFNFKSArCiAgIyBUZXh0IGFubm90YXRpb24gZm9yIHRoZSBDb250cm9sIGFuZCBQd1BEIGRpc3RyaWJ1dGlvbnMKICBhbm5vdGF0ZSgKICAgICd0ZXh0JywKICAgIHggPSAtLjEzKjEwMCwgIyBQbGF5IGFyb3VuZCB3aXRoIHRoZSBjb29yZGluYXRlcyB1bnRpbCB5b3UncmUgc2F0aXNmaWVkCiAgICB5ID0gMy4zLAogICAgbGFiZWwgPSAiQm90aCBDb250cm9sIGFuZCBQd1BEXG53ZXJlIHJvYnVzdGx5IGxlc3MgaW50ZWxsaWdiaWxlXG53aXRoIEVNQSBzZW5zb3JzIG9uLi4uIiwKICAgIGhqdXN0ID0gMCwKICAgIHNpemUgPSAyLAogICAgYWxwaGEgPSAuOCwKICAgIGNvbG9yID0gImJsYWNrIgogICkgKwogICMgQXJyb3cgdG8gdGhlIENvbnRyb2wgZGlzdHJpYnV0aW9uCiAgYW5ub3RhdGUoCiAgICAnY3VydmUnLAogICAgeCA9IC0uMDk1KjEwMCwgIyBQbGF5IGFyb3VuZCB3aXRoIHRoZSBjb29yZGluYXRlcyB1bnRpbCB5b3UncmUgc2F0aXNmaWVkCiAgICB5ID0gMy4xLAogICAgeGVuZCA9IC0uMDMqMTAwLAogICAgeWVuZCA9IDIuOTYsCiAgICBsaW5ld2lkdGggPSAuNCwKICAgIGN1cnZhdHVyZSA9IDAuMiwKICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjEsICdjbScpLCB0eXBlID0gImNsb3NlZCIpLAogICAgYWxwaGEgPSAxLAogICAgY29sb3IgPSAiZGFya2dyZXkiCiAgKSArCiAgIyBBcnJvdyB0byB0aGUgUHdQRCBkaXN0cmlidXRpb24KICBhbm5vdGF0ZSgKICAgICdjdXJ2ZScsCiAgICB4ID0gLS4wOTYqMTAwLCAjIFBsYXkgYXJvdW5kIHdpdGggdGhlIGNvb3JkaW5hdGVzIHVudGlsIHlvdSdyZSBzYXRpc2ZpZWQKICAgIHkgPSAzLjEsCiAgICB4ZW5kID0gLS4wNjUqMTAwLAogICAgeWVuZCA9IDIuMywKICAgIGxpbmV3aWR0aCA9IC40LAogICAgY3VydmF0dXJlID0gMC4yLAogICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMSwgJ2NtJyksIHR5cGUgPSAiY2xvc2VkIiksCiAgICBhbHBoYSA9IDEsCiAgICBjb2xvciA9ICJkYXJrZ3JleSIKICApICsKICAjIFRleHQgZm9yIHRoZSBjb250cmFzdCBkaXN0cmlidXRpb24KICBhbm5vdGF0ZSgKICAgICd0ZXh0JywKICAgIHggPSAtLjA3KjEwMCwgIyBQbGF5IGFyb3VuZCB3aXRoIHRoZSBjb29yZGluYXRlcyB1bnRpbCB5b3UncmUgc2F0aXNmaWVkCiAgICB5ID0gMC43MywKICAgIGxhYmVsID0gIi4uLiBidXQgdGhlc2UgZWZmZWN0c1xud2VyZSByb2J1c3RseSBkaWZmZXJlbnRcbmJldHdlZW4gdGhlIGdyb3Vwcy4iLAogICAgaGp1c3QgPSAxLAogICAgc2l6ZSA9IDIsCiAgICBhbHBoYSA9IC44LAogICAgY29sb3IgPSAiYmxhY2siCiAgKSArCiAgICAjIEFycm93IHRvIHRoZSBjb250cmFzdCBkaXN0cmlidXRpb24KICBhbm5vdGF0ZSgKICAgICdjdXJ2ZScsCiAgICB4ID0gLS4wNjUqMTAwLCAjIFBsYXkgYXJvdW5kIHdpdGggdGhlIGNvb3JkaW5hdGVzIHVudGlsIHlvdSdyZSBzYXRpc2ZpZWQKICAgIHkgPSAwLjczLAogICAgeGVuZCA9IC0uMDQ1KjEwMCwKICAgIHllbmQgPSAuOTUsCiAgICBsaW5ld2lkdGggPSAuNCwKICAgIGN1cnZhdHVyZSA9IDAuMiwKICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjEsICdjbScpLCB0eXBlID0gImNsb3NlZCIpLAogICAgYWxwaGEgPSAxLAogICAgY29sb3IgPSAiZGFya2dyZXkiCiAgKSArCiAgbGFicygKICAgIHggPSAiQXZlcmFnZSBtYXJnaW5hbCBlZmZlY3Qgb2Ygc2Vuc29ycyBlZmZlY3RzICglKSIsCiAgICB5ID0gTlVMTCwKICAgIHRpdGxlID0gIihiKSBSZXNlYXJjaCBRdWVzdGlvbiAxIiwKICAgIHN1YnRpdGxlID0gIlNlbnNvciBlZmZlY3QgKFdpdGggU2Vuc29ycyAtIEJlZm9yZSBTZW5zb3JzKVxucGVyIGdyb3VwIGFuZCB0aGUgZWZmZWN0IGNvbnRyYXN0IGJldHdlZW4gZ3JvdXBzLiIsCiAgICBmaWxsID0gIlJvYnVzdCBhdCA5NSUgSFBEIEludGVydmFsICYgcGQiCiAgKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpCiAgKQoKcGxvdF9SUTFfSW50CgpwbG90X1JRMl9JbnQgPC0gZ2dwbG90KAogIGRhdGFfbWVDb250cmFzdHNfSW50ICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAiYWZ0ZXIgLSBiZWZvcmUiKSwKICAgIGFlcyh4ID0gLnZhbHVlLCB5ID0gZ3JvdXAsIGZpbGwgPSByb2J1c3QpCikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGFscGhhID0gLjMpICsKICBzdGF0X2hhbGZleWUoYWxwaGEgPSAuOSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFM0I1Q0YiLCAiI0NDNzlBNyIpLAogICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpICsKICBsYWJzKAogICAgeCA9ICJBdmVyYWdlIG1hcmdpbmFsIGVmZmVjdCBvZiBhZnRlci1zZW5zb3JcbmVmZmVjdHMgKCUpIiwKICAgIHkgPSBOVUxMLAogICAgdGl0bGUgPSAiKGMpIFJlc2VhcmNoIFF1ZXN0aW9uIDIiLAogICAgc3VidGl0bGUgPSAiQWZ0ZXItc2Vuc29yIGVmZmVjdCAoQWZ0ZXIgU2Vuc29ycyAtXG5CZWZvcmUgU2Vuc29ycykgcGVyIGdyb3VwIGFuZCB0aGVcbmVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlEyX0ludAoKIyBDb21iaW5lZCBwbG90CnBsb3RfSW50IDwtICBwbG90X2dyYW5kTWVhbl9JbnQgKyBwbG90X1JRMV9JbnQgKyBwbG90X1JRMl9JbnQgKwogIHBhdGNod29yazo6cGxvdF9sYXlvdXQobmNvbCA9IDMsIGhlaWdodHMgPSBjKDEpLCBndWlkZXMgPSAiY29sbGVjdCIpICsKICBwbG90X2Fubm90YXRpb24odGl0bGUgPSAiSW50ZWxsaWdpYmlsaXR5IiwgI3N1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5ncyBhY3Jvc3MgZ3JvdXAvc2V2ZXJpdHkgYW5kIHNwZWFraW5nIGNvbmRpdGlvbnMuIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCnBsb3RfSW50CgpnZ3NhdmUoCiAgcGxvdCA9IHBsb3RfSW50LAogIGZpbGVuYW1lID0gIkZpZ3VyZXMvRmlnX0ludC5wbmciLAogIGhlaWdodCA9IDYsCiAgd2lkdGggPSAxMCwKICB1bml0ID0gImluIiwKICBzY2FsZSA9IC45LAogIGJnID0gIndoaXRlIgopCgpgYGAKCgojIDA3LiBOYXR1cmFsbmVzcwojIyBFeHBlY3RlZCBQb3N0ZXJpb3JzCmBgYHtyfQplcHNpbG9uIDwtIDFlLTUKIyBHZW5lcmF0ZSBleHBlY3RlZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBwb3N0ZXJpb3IKZGF0YV9wb3N0ZXJpb3JfTmF0IDwtIG1vZGVsX05hdCAlPiUKICB0aWR5YmF5ZXM6OmVwcmVkX2RyYXdzKAogICAgbmV3ZGF0YSA9IHRpZHlyOjpleHBhbmRfZ3JpZCgKICAgICAgZ3JvdXAgPSBjKCJDb250cm9sIiwgIlBEIiksCiAgICAgIHRpbWVfcG9pbnQgPSBjKCJiZWZvcmUiLCAic2Vuc29ycyIsICJhZnRlciIpLAogICAgICBzZXggPSBjKCJNYWxlIiwgIkZlbWFsZSIpLAogICAgICBhZ2UgPSBtZWFuKG1vZGVsX05hdCRkYXRhJGFnZSksICMgNjYuOTEgeW8KICAgICAgYXJ0aWNfcmF0ZSA9IG1lYW4obW9kZWxfTmF0JGRhdGEkYXJ0aWNfcmF0ZSksICMgNC44NSBzeWwvcwogICAgICB0cmlhbF9udW1iZXIgPSBtZWFuKG1vZGVsX05hdCRkYXRhJHRyaWFsX251bWJlcikgIyB0cmlhbCA5CiAgICApLAogICAgcmVfZm9ybXVsYSA9IE5BCiAgKSAlPiUKICBncm91cF9ieSguZHJhdywgZ3JvdXAsIHRpbWVfcG9pbnQpICU+JQogIHN1bW1hcml6ZSguZXByZWQgPSBtZWFuKC5lcHJlZCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICBncm91cCA9IGZhY3RvcigKICAgICAgZ3JvdXAsCiAgICAgIGxldmVscyA9IGMoIkNvbnRyb2wiLCAiUEQiKSwKICAgICAgbGFiZWxzID0gYygiQ29udHJvbCIsICJQd1BEIikKICAgICksCiAgICAjZ3JvdXBpbmcgPSBwYXN0ZShzZXgsIGdyb3VwLCBzZXAgPSAiIC0gIiksCiAgICAjZ3JvdXBpbmcgPSBmYWN0b3IoZ3JvdXBpbmcsCiAgICAjICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTWFsZSAtIENvbnRyb2wiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hbGUgLSBQd1BEIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBDb250cm9sIiwKICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBQd1BEIikpLAogICAgdGltZV9wb2ludCA9IGZhY3RvcigKICAgICAgdGltZV9wb2ludCwKICAgICAgbGV2ZWxzID0gYygiYmVmb3JlIiwgInNlbnNvcnMiLCAiYWZ0ZXIiKSwKICAgICAgbGFiZWxzID0gYygiQmVmb3JlXG5TZW5zb3JzIiwgIldpdGhcblNlbnNvcnMiLCAiQWZ0ZXJcblNlbnNvcnMiKQogICAgKSwKICAgIC5lcHJlZCA9ICguZXByZWQgLSBlcHNpbG9uKSAvICgxIC0gMiAqIGVwc2lsb24pLAogICAgIyBTdGVwIDEgJiAyOiBSZXZlcnNlIHRoZSBvZmZzZXQgYW5kIHNjYWxpbmcKICAgIC5lcHJlZCA9IC5lcHJlZCAqIG5yb3coLikgLyAoKG5yb3coLikgLSAxKSArIC41KSwKICAgIC5lcHJlZCA9IC5lcHJlZCAqIDEwMAogICkKCnBsb3RfZ3JhbmRNZWFuX05hdCA8LSBnZ3Bsb3QoZGF0YV9wb3N0ZXJpb3JfTmF0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IC5lcHJlZCwgeSA9IHRpbWVfcG9pbnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gZ3JvdXApKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBnZ29rYWJlaXRvOjpzY2FsZV9maWxsX29rYWJlX2l0byhvcmRlciA9IGMoMiwgMSkpICsKICBsYWJzKHggPSAiUHJlZGljdGVkIG5hdHVyYWxuZXNzIHJhdGluZyAoJSkiLCB5ID0gTlVMTCwKICAgICAgIGZpbGwgPSAiR3JvdXAiLAogICAgICAgdGl0bGUgPSAiKGEpIFBvc3RlcmlvciBQcmVkaWN0aW9ucyIsCiAgICAgICBzdWJ0aXRsZSA9ICJQcmVkaWN0ZWQgbmF0dXJhbG5lc3MgcmF0aW5nIGFmdGVyIGNvbnRyb2xsaW5nXG5mb3Igc3BlYWtlciBhZ2UsIHNleCwgYXJ0aWN1bGF0aW9uIHJhdGUsXG5hbmQgdHJpYWwgbnVtYmVyLiIpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLDEwMCkpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9heGlzVGl0bGUpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKSkgICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpCmBgYAoKIyMgTUU6IFRpbWVwb2ludCB4IEdyb3VwCmBgYHtyfQpyb2J1c3RfTmF0IDwtIHJpbzo6aW1wb3J0KCJ3b3JraW5nRGF0YS9kYXRhX05hdC5SRFMiKSRwYWlyd2lzZSAlPiUKICBkcGx5cjo6c2VsZWN0KGNvbnRyYXN0LCBncm91cCwgcm9idXN0KQoKZXBzaWxvbiA8LSAxZS01CmRhdGFfbWVDb250cmFzdHNfTmF0IDwtIG1vZGVsX05hdCAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCB8IGdyb3VwLAogICAgICAgICAgICAgICAgICAgZXByZWQgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgcmVfZm9ybXVsYSA9IE5BLCkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QobWV0aG9kID0gInJldnBhaXJ3aXNlIikgJT4lCiAgZ2F0aGVyX2VtbWVhbnNfZHJhd3MoKSAlPiUKICBkcGx5cjo6bXV0YXRlKAogICAgLnZhbHVlID0gKC52YWx1ZSAtIGVwc2lsb24pIC8gKDEgLSAyICogZXBzaWxvbiksCiAgICAjIFN0ZXAgMSAmIDI6IFJldmVyc2UgdGhlIG9mZnNldCBhbmQgc2NhbGluZwogICAgLnZhbHVlID0gLnZhbHVlICogbnJvdyguKSAvICgobnJvdyguKSAtIDEpICsgLjUpLAogICAgLnZhbHVlID0gLnZhbHVlICogMTAwCiAgKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbnRyYXN0ICE9ICJhZnRlciAtIHNlbnNvcnMiKQoKIyBDb21wdXRlIHRoZSBpbnRlcmFjdGlvbiBjb250cmFzdCAoZGlmZmVyZW5jZSBpbiBjb250cmFzdHMgYmV0d2VlbiBncm91cHMpCmludGVyYWN0aW9uX2NvbnRyYXN0IDwtIG1vZGVsX05hdCAlPiUKICBlbW1lYW5zOjplbW1lYW5zKH4gdGltZV9wb2ludCAqIGdyb3VwLCBlcHJlZCA9IFRSVUUsIHJlX2Zvcm11bGEgPSBOQSkgJT4lCiAgZW1tZWFuczo6Y29udHJhc3QoaW50ZXJhY3Rpb24gPSAicmV2cGFpcndpc2UiKSAlPiUKICBnYXRoZXJfZW1tZWFuc19kcmF3cygpICU+JQogIGRwbHlyOjptdXRhdGUoCiAgICAudmFsdWUgPSAoLnZhbHVlIC0gZXBzaWxvbikgLyAoMSAtIDIgKiBlcHNpbG9uKSwKICAgICMgU3RlcCAxICYgMjogUmV2ZXJzZSB0aGUgb2Zmc2V0IGFuZCBzY2FsaW5nCiAgICAudmFsdWUgPSAudmFsdWUgKiBucm93KC4pIC8gKChucm93KC4pIC0gMSkgKyAuNSksCiAgICAudmFsdWUgPSAudmFsdWUgKiAxMDAKICApICU+JQogIGRwbHlyOjpyZW5hbWUoY29udHJhc3QgPSB0aW1lX3BvaW50X3JldnBhaXJ3aXNlLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBncm91cF9yZXZwYWlyd2lzZSkgJT4lCiAgZHBseXI6OmZpbHRlcihjb250cmFzdCAhPSAiYWZ0ZXIgLSBzZW5zb3JzIikKCmRhdGFfbWVDb250cmFzdHNfTmF0IDwtIGJhc2U6OnJiaW5kKGRhdGFfbWVDb250cmFzdHNfTmF0LCBpbnRlcmFjdGlvbl9jb250cmFzdCkgICU+JQogIGRwbHlyOjptdXRhdGUoZ3JvdXAgPSBjYXNlX3doZW4oCiAgICBncm91cCA9PSAiUEQiIH4gIlB3UEQiLAogICAgZ3JvdXAgPT0gIkNvbnRyb2wiIH4gIkNvbnRyb2wiLAogICAgZ3JvdXAgPT0gIlBEIC0gQ29udHJvbCIgfiAiUHdQRCAtXG5Db250cm9sIgogICkpICU+JQogIGJhc2U6Om1lcmdlKC4sIHJvYnVzdF9OYXQpICU+JQogIGRwbHlyOjptdXRhdGUocm9idXN0ID0gZmFjdG9yKHJvYnVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJub3Qgcm9idXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyb2J1c3QiKSkpCgojYmF5ZXN0ZXN0Ujo6cF9kaXJlY3Rpb24oZGF0YV9tZUNvbnRyYXN0c19OYXQpCgpwbG90X1JRMV9OYXQgPC0gZ2dwbG90KAogIGRhdGFfbWVDb250cmFzdHNfTmF0ICU+JQogICAgZHBseXI6OmZpbHRlcihjb250cmFzdCA9PSAic2Vuc29ycyAtIGJlZm9yZSIpLAogICAgYWVzKHggPSAudmFsdWUsIHkgPSBncm91cCwgZmlsbCA9IHJvYnVzdCkKKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgYWxwaGEgPSAuMykgKwogIHN0YXRfaGFsZmV5ZShhbHBoYSA9IC45KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UzQjVDRiIsICIjQ0M3OUE3IiksCiAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB4ID0gIkF2ZXJhZ2UgbWFyZ2luYWwgZWZmZWN0IG9mIHNlbnNvcnMgZWZmZWN0cyAoJSkiLAogICAgeSA9IE5VTEwsCiAgICB0aXRsZSA9ICIoYikgUmVzZWFyY2ggUXVlc3Rpb24gMSIsCiAgICBzdWJ0aXRsZSA9ICJTZW5zb3IgZWZmZWN0IChXaXRoIFNlbnNvcnMgLSBCZWZvcmUgU2Vuc29ycylcbnBlciBncm91cCBhbmQgdGhlIGVmZmVjdCBjb250cmFzdCBiZXR3ZWVuIGdyb3Vwcy4iLAogICAgZmlsbCA9ICJSb2J1c3QgYXQgOTUlIEhQRCBJbnRlcnZhbCAmIHBkIgogICkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgdGhlbWVfY2xlYW4oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX2F4aXNUaXRsZSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90VGl0bGUpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfcGxvdFN1YnRpdGxlKQogICkKCnBsb3RfUlExX05hdAoKcGxvdF9SUTJfTmF0IDwtIGdncGxvdCgKICBkYXRhX21lQ29udHJhc3RzX05hdCAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoY29udHJhc3QgPT0gImFmdGVyIC0gYmVmb3JlIiksCiAgICBhZXMoeCA9IC52YWx1ZSwgeSA9IGdyb3VwLCBmaWxsID0gcm9idXN0KQopICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBhbHBoYSA9IC4zKSArCiAgc3RhdF9oYWxmZXllKGFscGhhID0gLjkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRTNCNUNGIiwgIiNDQzc5QTciKSwKICAgICAgICAgICAgICAgICAgICAgZHJvcCA9IEZBTFNFKSArCiAgbGFicygKICAgIHggPSAiQXZlcmFnZSBtYXJnaW5hbCBlZmZlY3Qgb2YgYWZ0ZXItc2Vuc29yc1xuZWZmZWN0cyAoJSkiLAogICAgeSA9IE5VTEwsCiAgICB0aXRsZSA9ICIoYykgUmVzZWFyY2ggUXVlc3Rpb24gMiIsCiAgICBzdWJ0aXRsZSA9ICJBZnRlci1zZW5zb3IgZWZmZWN0IChBZnRlciBTZW5zb3JzIC1cbkJlZm9yZSBTZW5zb3JzKSBwZXIgZ3JvdXAgYW5kIHRoZVxuZWZmZWN0IGNvbnRyYXN0IGJldHdlZW4gZ3JvdXBzLiIsCiAgICBmaWxsID0gIlJvYnVzdCBhdCA5NSUgSFBEIEludGVydmFsICYgcGQiCiAgKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICB0aGVtZV9jbGVhbigpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gdGV4dFNpemVfYXhpc1RpdGxlKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHRleHRTaXplX3Bsb3RUaXRsZSksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSB0ZXh0U2l6ZV9wbG90U3VidGl0bGUpCiAgKQoKcGxvdF9SUTJfTmF0CgojIENvbWJpbmVkIHBsb3QKcGxvdF9OYXQgPC0gIHBsb3RfZ3JhbmRNZWFuX05hdCArIHBsb3RfUlExX05hdCArIHBsb3RfUlEyX05hdCArCiAgcGF0Y2h3b3JrOjpwbG90X2xheW91dChuY29sID0gMywKICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodHMgPSBjKDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgZ3VpZGVzID0gImNvbGxlY3QiKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gIk5hdHVyYWxuZXNzIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCnBsb3RfTmF0CgpnZ3NhdmUoCiAgcGxvdCA9IHBsb3RfTmF0LAogIGZpbGVuYW1lID0gIkZpZ3VyZXMvRmlnX05hdC5wbmciLAogIGhlaWdodCA9IDYsCiAgd2lkdGggPSAxMCwKICB1bml0ID0gImluIiwKICBzY2FsZSA9IC45LAogIGJnID0gIndoaXRlIgopCgpgYGAKIyBTMDEuIEluZGl2aWR1YWwgVmFyaWFiaWxpdHkKYGBge3J9CndvcmtpbmdEYXRhX2FydGljUmF0ZSA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9hcnRpY1JhdGUuUkRTIikKd29ya2luZ0RhdGFfQUFWUyA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9BQVZTLlJEUyIpCndvcmtpbmdEYXRhX00xcyA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9NMXMuUkRTIikKd29ya2luZ0RhdGFfTTFzaCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9NMXNoLlJEUyIpCndvcmtpbmdEYXRhX00ycyA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9NMnMuUkRTIikKd29ya2luZ0RhdGFfTTJzaCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9NMnNoLlJEUyIpCndvcmtpbmdEYXRhX0ludCA8LSBiYXNlOjpyZWFkUkRTKGZpbGUgPSAid29ya2luZ0RhdGEvZGF0YV9JbnQuUkRTIikKd29ya2luZ0RhdGFfTmF0IDwtIGJhc2U6OnJlYWRSRFMoZmlsZSA9ICJ3b3JraW5nRGF0YS9kYXRhX05hdC5SRFMiKQoKYWxsRGF0YSA8LSBiaW5kX3Jvd3MoCiAgd29ya2luZ0RhdGFfYXJ0aWNSYXRlJG1vZGVsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUobWVhc3VyZSA9ICJBcnRpY3VsYXRpb24gUmF0ZSIpICU+JQogICAgZHBseXI6OnJlbmFtZSh2YWx1ZSA9IGFydGljUmF0ZSksCiAgCiAgd29ya2luZ0RhdGFfQUFWUyRtb2RlbERhdGEgJT4lCiAgICBkcGx5cjo6bXV0YXRlKG1lYXN1cmUgPSAiQUFWUyIpICU+JQogICAgZHBseXI6OnJlbmFtZSh2YWx1ZSA9IEFBVlMpLAogIAogIHdvcmtpbmdEYXRhX00xcyRtb2RlbERhdGEgJT4lCiAgICBkcGx5cjo6bXV0YXRlKG1lYXN1cmUgPSAiTTEgZm9yIC9zLyIpICU+JQogICAgZHBseXI6OnJlbmFtZSh2YWx1ZSA9IE0xcyksCiAgCiAgd29ya2luZ0RhdGFfTTJzJG1vZGVsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUobWVhc3VyZSA9ICJNMiBmb3IgL3MvIikgJT4lCiAgICBkcGx5cjo6cmVuYW1lKHZhbHVlID0gTTJzKSwKICAKICB3b3JraW5nRGF0YV9NMXNoJG1vZGVsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUobWVhc3VyZSA9ICJNMSBmb3IgL8qDLyIpICU+JQogICAgZHBseXI6OnJlbmFtZSh2YWx1ZSA9IE0xc2gpLAogIAogIHdvcmtpbmdEYXRhX00yc2gkbW9kZWxEYXRhICU+JQogICAgZHBseXI6Om11dGF0ZShtZWFzdXJlID0gIk0yIGZvciAvyoMvIikgJT4lCiAgICBkcGx5cjo6cmVuYW1lKHZhbHVlID0gTTJzaCksCiAgCiAgd29ya2luZ0RhdGFfSW50JG1vZGVsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUobWVhc3VyZSA9ICJJbnRlbGxpZ2liaWxpdHkiLAogICAgICAgICAgICAgICAgICBJbnQgPSBJbnQqMTAwKSAlPiUKICAgIGRwbHlyOjpyZW5hbWUodmFsdWUgPSBJbnQpLAogIAogIHdvcmtpbmdEYXRhX05hdCRtb2RlbERhdGEgJT4lCiAgICBkcGx5cjo6bXV0YXRlKG1lYXN1cmUgPSAiTmF0dXJhbG5lc3MiLAogICAgICAgICAgICAgICAgICBOYXQgPSBOYXQqMTAwKSAlPiUKICAgIGRwbHlyOjpyZW5hbWUodmFsdWUgPSBOYXQpCikgJT4lCiAgZHBseXI6Om11dGF0ZSh0aW1lX3BvaW50ID0gZmFjdG9yKHRpbWVfcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoImJlZm9yZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNlbnNvcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZnRlciIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJCZWZvcmVcblNlbnNvcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXaXRoXG5TZW5zb3JzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWZ0ZXJcblNlbnNvcnMiKSksCiAgICAgICAgICAgICAgICBtZWFzdXJlID0gZmFjdG9yKG1lYXN1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkFydGljdWxhdGlvbiBSYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUFWUyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk0xIGZvciAvcy8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNMiBmb3IgL3MvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTTEgZm9yIC/Kgy8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNMiBmb3IgL8qDLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludGVsbGlnaWJpbGl0eSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5hdHVyYWxuZXNzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkFydGljdWxhdGlvbiBSYXRlIChzeWwvcykiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQVZTIChtZWzCsikiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNMSBmb3IgL3MvIChrSHopIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTTIgZm9yIC9zLyAoa0h6KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk0xIGZvciAvyoMvIChrSHopIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTTIgZm9yIC/Kgy8gKGtIeikiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbnRlbGxpZ2liaWxpdHkgKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmF0dXJhbG5lc3MgKCUpIikpLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBmYWN0b3IoZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBEIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlB3UEQiKSksCiAgICAgICAgICAgICAgICBncm91cGluZyA9IHBhc3RlKHNleCwgZ3JvdXAsIHNlcCA9ICIgLSAiKSwKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gZmFjdG9yKGdyb3VwaW5nLAogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTWFsZSAtIENvbnRyb2wiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFsZSAtIFB3UEQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIC0gQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUgLSBQd1BEIikpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkobWVhc3VyZSwgc3BlYWtlcl9pZCwgZ3JvdXAsIHNleCwgZ3JvdXBpbmcsIGFnZSwgdGltZV9wb2ludCkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICBkcGx5cjo6dW5ncm91cCgpCgpwbG90RGF0YSA8LSBiaW5kX3Jvd3MoCiAgYWxsRGF0YSAlPiUKICAgIGRwbHlyOjptdXRhdGUocGxvdCA9ICJBbGwgRGF0YSIpLAogIGFsbERhdGEgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKHRpbWVfcG9pbnQgIT0gIkFmdGVyXG5TZW5zb3JzIikgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHBsb3QgPSAiU2Vuc29yIEVmZmVjdHMiKSwKICBhbGxEYXRhICU+JQogICAgZHBseXI6OmZpbHRlcih0aW1lX3BvaW50ICE9ICJXaXRoXG5TZW5zb3JzIikgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHBsb3QgPSAiQWZ0ZXItU2Vuc29yIEVmZmVjdHMiKSwKKSAlPiUKICBkcGx5cjo6bXV0YXRlKHBsb3QgPSBmYWN0b3IocGxvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiQWxsIERhdGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZW5zb3IgRWZmZWN0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFmdGVyLVNlbnNvciBFZmZlY3RzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkFsbCBEYXRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2Vuc29yIEVmZmVjdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBZnRlci1TZW5zb3JcbkVmZmVjdHMiKSkpICU+JQogIGRwbHlyOjpmaWx0ZXIocGxvdCAhPSAiQWxsIERhdGEiKQoKcGxvdF9yYXdEYXRhX3NlbnNvckVmZmVjdHMgPC0gcGxvdERhdGEgJT4lCiAgZHBseXI6OmZpbHRlcihwbG90ID09ICJTZW5zb3IgRWZmZWN0cyIpICU+JQogIGdncGxvdCgpICsKICBhZXMoeCA9IHRpbWVfcG9pbnQsIHkgPSB2YWx1ZSwgY29sb3IgPSBncm91cCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzcGVha2VyX2lkKSwgYWxwaGEgPSAuMykgKwogIGdlb21fbGluZSgKICAgIGRhdGEgPSBwbG90RGF0YSAlPiUKICAgICAgZHBseXI6OmZpbHRlcihwbG90ID09ICJTZW5zb3IgRWZmZWN0cyIpICU+JQogICAgICBkcGx5cjo6Z3JvdXBfYnkobWVhc3VyZSwgZ3JvdXAsIHNleCwgdGltZV9wb2ludCwgcGxvdCkgJT4lCiAgICAgIGRwbHlyOjpzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlKSksCiAgICBhZXMoZ3JvdXAgPSBncm91cCksCiAgICBhbHBoYSA9IC44LAogICAgbGluZXdpZHRoID0gMS41CiAgKSArCiAgI2dlb21fcG9pbnQoYWVzKHNoYXBlID0gc2V4KSkgKwogIGdnb2thYmVpdG86OnNjYWxlX2NvbG9yX29rYWJlX2l0byhvcmRlciA9IGMoMiwxKSkgKwogIGZhY2V0X2dyaWQobWVhc3VyZSB+IHNleCwgc2NhbGVzID0gImZyZWUiLCBzd2l0Y2ggPSAieSIpICsKICBsYWJzKHggPSBOVUxMLAogICAgICAgeSA9IE5VTEwsCiAgICAgICBjb2xvciA9ICJHcm91cCIsCiAgICAgICBzaGFwZSA9ICJTZXgiLAogICAgICAgdGl0bGUgPSAiU2Vuc29yIEVmZmVjdHMiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShleHBhbmQ9ZXhwYW5zaW9uKGMoLjM1LC4zNSkpKSArCiAgdGhlbWVfY2xlYW4oKSAmCiAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSAiYmxhY2siKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9IE5BKSwKICAgICAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsCiAgICAgICAgc3RyaXAudGV4dC55LmxlZnQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBmYWNlPSJwbGFpbiIsIGhqdXN0ID0gMSksKQpwbG90X3Jhd0RhdGFfc2Vuc29yRWZmZWN0cwoKcGxvdF9yYXdEYXRhX2FmdGVyU2Vuc29yRWZmZWN0cyA8LSBwbG90RGF0YSAlPiUKICBkcGx5cjo6ZmlsdGVyKHBsb3QgPT0gIkFmdGVyLVNlbnNvclxuRWZmZWN0cyIpICU+JQogIGdncGxvdCgpICsKICBhZXMoeCA9IHRpbWVfcG9pbnQsIHkgPSB2YWx1ZSwgY29sb3IgPSBncm91cCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzcGVha2VyX2lkKSwgYWxwaGEgPSAuMykgKwogIGdlb21fbGluZSgKICAgIGRhdGEgPSBwbG90RGF0YSAlPiUKICAgICAgZHBseXI6OmZpbHRlcihwbG90ID09ICJBZnRlci1TZW5zb3JcbkVmZmVjdHMiKSAlPiUKICAgICAgZHBseXI6Omdyb3VwX2J5KG1lYXN1cmUsIGdyb3VwLCBzZXgsIHRpbWVfcG9pbnQsIHBsb3QpICU+JQogICAgICBkcGx5cjo6c3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSkpLAogICAgYWVzKGdyb3VwID0gZ3JvdXApLAogICAgYWxwaGEgPSAuOCwKICAgIGxpbmV3aWR0aCA9IDEuNQogICkgKwogICNnZW9tX3BvaW50KGFlcyhzaGFwZSA9IHNleCkpICsKICBnZ29rYWJlaXRvOjpzY2FsZV9jb2xvcl9va2FiZV9pdG8ob3JkZXIgPSBjKDIsMSkpICsKICBmYWNldF9ncmlkKG1lYXN1cmUgfiBzZXgsIHNjYWxlcyA9ICJmcmVlIikgKwogIGxhYnMoeCA9IE5VTEwsCiAgICAgICB5ID0gTlVMTCwKICAgICAgIGNvbG9yID0gIkdyb3VwIiwKICAgICAgIHNoYXBlID0gIlNleCIsCiAgICAgICB0aXRsZSA9ICJBZnRlci1TZW5zb3IgRWZmZWN0cyIpICsKICBzY2FsZV94X2Rpc2NyZXRlKGV4cGFuZD1leHBhbnNpb24oYyguMzUsLjM1KSkpICsKICB0aGVtZV9jbGVhbigpICYKICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLCBjb2xvciA9ICJibGFjayIpLAogICAgICAgICNzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9IE5BKSwKICAgICAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsCiAgICAgICAgI3N0cmlwLnRleHQueS5sZWZ0ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgZmFjZT0icGxhaW4iLCBoanVzdCA9IDEpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAudGV4dC55LiA9IGVsZW1lbnRfYmxhbmsoKSkKcGxvdF9yYXdEYXRhX2FmdGVyU2Vuc29yRWZmZWN0cwoKcGxvdF9yYXdEYXRhIDwtIHBsb3RfcmF3RGF0YV9zZW5zb3JFZmZlY3RzICsgcGxvdF9yYXdEYXRhX2FmdGVyU2Vuc29yRWZmZWN0cyArCiAgcGF0Y2h3b3JrOjpwbG90X2xheW91dChuY29sID0gMiwgI2hlaWdodHMgPSBjKDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgZ3VpZGVzID0gImNvbGxlY3QiKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gIlJhdyBEYXRhIiwgI3N1YnRpdGxlID0gIlByZWRpY3RlZCBpbnRlbGxpZ2liaWxpdHkgcmF0aW5ncyBhY3Jvc3MgZ3JvdXAvc2V2ZXJpdHkgYW5kIHNwZWFraW5nIGNvbmRpdGlvbnMuIiwKICAgICAgICAgICAgICAgICAgdGhlbWUgPSB0aGVtZV9jbGVhbigpKSAmCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgc3RyaXAuYmFja2dyb3VuZC5yaWdodCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHN0cmlwLnRleHQueS5yaWdodCA9IGVsZW1lbnRfYmxhbmsoKQogICkKCmdnc2F2ZSgKICBwbG90ID0gcGxvdF9yYXdEYXRhLAogIGZpbGVuYW1lID0gIkZpZ3VyZXMvU3VwRmlnX3Jhd0RhdGEucG5nIiwKICBoZWlnaHQgPSAxMCwKICB3aWR0aCA9IDksCiAgdW5pdCA9ICJpbiIsCiAgc2NhbGUgPSAuOSwKICBiZyA9ICJ3aGl0ZSIKKQpgYGAKCg==